From f1fdcff3518e802db8f05af4d1f65069c5e40e49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20R=C3=B6hling?= Date: Mon, 19 Jun 2023 11:01:40 +0200 Subject: [PATCH] New upstream version 1.6.4+ds --- .github/workflows/benchmark.yml | 8 +- .github/workflows/main.yml | 145 +++--- .github/workflows/nightly.yml | 44 +- CMakeLists.txt | 6 +- COPYING | 30 ++ README.md | 11 +- ci/build.sh | 20 +- ci/docker/xenial | 16 +- ci/setup-mingw-build.sh | 4 +- ci/setup-win32-build.sh | 27 ++ ci/test.sh | 129 +++++- cmake/ExperimentalFeatures.cmake | 23 + docs/changelog.md | 151 +++++- examples/cat-file.c | 10 +- examples/fetch.c | 6 +- examples/for-each-ref.c | 4 +- examples/general.c | 43 +- examples/index-pack.c | 9 +- examples/log.c | 2 +- examples/ls-remote.c | 2 +- examples/rev-list.c | 10 +- examples/rev-parse.c | 2 +- examples/show-index.c | 4 +- fuzzers/commit_graph_fuzzer.c | 6 +- fuzzers/midx_fuzzer.c | 6 +- fuzzers/objects_fuzzer.c | 2 +- fuzzers/packfile_fuzzer.c | 28 +- include/git2.h | 1 + include/git2/common.h | 19 +- include/git2/deprecated.h | 6 + include/git2/diff.h | 2 +- include/git2/experimental.h | 20 + include/git2/indexer.h | 29 ++ include/git2/object.h | 30 +- include/git2/odb.h | 65 ++- include/git2/odb_backend.h | 128 +++++- include/git2/oid.h | 130 +++++- include/git2/repository.h | 21 +- include/git2/stash.h | 66 ++- include/git2/strarray.h | 13 - include/git2/sys/odb_backend.h | 2 +- include/git2/sys/transport.h | 12 + include/git2/version.h | 8 +- package.json | 2 +- src/CMakeLists.txt | 6 - src/cli/CMakeLists.txt | 7 +- src/cli/cmd_hash_object.c | 35 +- src/cli/opt.c | 2 +- src/libgit2/CMakeLists.txt | 39 +- src/libgit2/annotated_commit.c | 2 +- src/libgit2/annotated_commit.h | 2 +- src/libgit2/attr_file.c | 2 +- src/libgit2/attrcache.c | 2 +- src/libgit2/blame.c | 2 + src/libgit2/blob.c | 6 +- src/libgit2/blob.h | 4 +- src/libgit2/branch.c | 4 +- src/libgit2/cherrypick.c | 6 +- src/libgit2/clone.c | 33 +- src/libgit2/commit.c | 69 ++- src/libgit2/commit.h | 34 +- src/libgit2/commit_graph.c | 79 ++-- src/libgit2/commit_graph.h | 3 + src/libgit2/commit_list.c | 8 +- src/libgit2/config.c | 9 +- src/libgit2/config_file.c | 4 +- src/libgit2/describe.c | 16 +- src/libgit2/diff.c | 6 +- src/libgit2/diff_file.c | 21 +- src/libgit2/diff_generate.c | 29 +- src/libgit2/diff_print.c | 10 +- src/libgit2/diff_tform.c | 4 + src/libgit2/email.c | 4 +- src/libgit2/experimental.h.in | 13 + src/libgit2/fetch.c | 9 +- src/libgit2/fetchhead.c | 8 +- src/libgit2/ident.c | 6 +- src/libgit2/index.c | 25 +- src/libgit2/indexer.c | 151 ++++-- src/libgit2/iterator.c | 6 +- src/libgit2/libgit2.c | 19 + src/libgit2/merge.c | 6 +- src/libgit2/midx.c | 31 +- src/libgit2/mwindow.c | 7 +- src/libgit2/mwindow.h | 5 +- src/libgit2/notes.c | 10 +- src/libgit2/object.c | 114 ++++- src/libgit2/object.h | 15 +- src/libgit2/odb.c | 263 +++++++++-- src/libgit2/odb.h | 47 +- src/libgit2/odb_loose.c | 198 +++++--- src/libgit2/odb_pack.c | 140 ++++-- src/libgit2/oid.c | 214 +++++---- src/libgit2/oid.h | 192 +++++++- src/libgit2/pack-objects.c | 19 +- src/libgit2/pack.c | 161 ++++--- src/libgit2/pack.h | 44 +- src/libgit2/parse.c | 7 +- src/libgit2/patch_parse.c | 10 +- src/libgit2/push.c | 16 +- src/libgit2/reader.c | 2 +- src/libgit2/rebase.c | 37 +- src/libgit2/refdb_fs.c | 109 +++-- src/libgit2/reflog.c | 12 +- src/libgit2/reflog.h | 3 +- src/libgit2/refs.c | 2 + src/libgit2/remote.c | 75 +-- src/libgit2/remote.h | 40 ++ src/libgit2/repository.c | 248 ++++++++-- src/libgit2/repository.h | 9 + src/libgit2/reset.c | 4 +- src/libgit2/revert.c | 8 +- src/libgit2/revparse.c | 30 +- src/libgit2/revwalk.c | 6 +- src/libgit2/stash.c | 227 ++++++++-- src/libgit2/strarray.c | 1 + src/libgit2/strarray.h | 25 + src/libgit2/streams/openssl.c | 2 +- src/libgit2/streams/openssl_dynamic.c | 10 +- src/libgit2/streams/socket.c | 5 +- src/libgit2/submodule.c | 8 +- src/libgit2/sysdir.c | 301 +++++++++++- src/libgit2/sysdir.h | 50 +- src/libgit2/tag.c | 39 +- src/libgit2/tag.h | 4 +- src/libgit2/threadstate.h | 2 +- src/libgit2/transports/http.c | 15 +- src/libgit2/transports/httpclient.c | 9 + src/libgit2/transports/httpclient.h | 10 + src/libgit2/transports/local.c | 14 + src/libgit2/transports/smart.c | 35 ++ src/libgit2/transports/smart.h | 11 +- src/libgit2/transports/smart_pkt.c | 192 ++++++-- src/libgit2/transports/smart_protocol.c | 54 ++- src/libgit2/transports/ssh.c | 127 +++--- src/libgit2/transports/winhttp.c | 19 +- src/libgit2/tree-cache.c | 8 +- src/libgit2/tree.c | 38 +- src/libgit2/tree.h | 4 +- src/libgit2/worktree.c | 5 + src/util/CMakeLists.txt | 7 +- src/util/fs_path.c | 2 +- src/util/futils.c | 3 - .../git2_features.h.in} | 0 src/util/git2_util.h | 4 +- src/util/hash.h | 13 + src/util/hash/openssl.c | 7 +- src/util/hash/rfc6234/sha.h | 112 ----- src/util/net.c | 428 ++++++++++++++---- src/util/net.h | 7 + src/util/posix.h | 2 + src/util/rand.c | 4 + src/util/regexp.c | 6 +- src/util/thread.h | 39 +- src/util/util.h | 1 + src/util/win32/findfile.c | 286 ------------ src/util/win32/findfile.h | 22 - tests/clar/clar.c | 70 ++- tests/clar/clar.h | 6 +- tests/clar/clar/print.h | 41 +- tests/clar/clar/summary.h | 29 +- tests/clar/clar_libgit2.c | 108 ++++- tests/clar/clar_libgit2.h | 48 +- tests/clar/main.c | 1 + tests/libgit2/CMakeLists.txt | 6 +- tests/libgit2/apply/apply_helpers.c | 2 +- tests/libgit2/apply/both.c | 12 +- tests/libgit2/apply/callbacks.c | 2 +- tests/libgit2/apply/check.c | 6 +- tests/libgit2/apply/index.c | 10 +- tests/libgit2/apply/tree.c | 6 +- tests/libgit2/apply/workdir.c | 8 +- tests/libgit2/blame/blame_helpers.c | 2 +- tests/libgit2/blame/getters.c | 10 +- tests/libgit2/checkout/binaryunicode.c | 9 +- tests/libgit2/checkout/conflict.c | 6 +- tests/libgit2/checkout/index.c | 6 +- tests/libgit2/checkout/tree.c | 36 +- tests/libgit2/checkout/typechange.c | 2 +- tests/libgit2/cherrypick/bare.c | 12 +- tests/libgit2/cherrypick/workdir.c | 36 +- tests/libgit2/commit/commit.c | 12 +- tests/libgit2/commit/parent.c | 2 +- tests/libgit2/commit/parse.c | 12 +- tests/libgit2/commit/write.c | 50 +- tests/libgit2/config/find.c | 11 + tests/libgit2/config/include.c | 12 +- tests/libgit2/config/read.c | 9 +- tests/libgit2/core/oid.c | 238 +++++++--- tests/libgit2/core/oidmap.c | 17 +- tests/libgit2/core/opts.c | 15 +- tests/libgit2/core/pool.c | 9 +- tests/libgit2/core/structinit.c | 5 + tests/libgit2/diff/binary.c | 26 +- tests/libgit2/diff/blob.c | 36 +- tests/libgit2/diff/diff_helpers.c | 2 +- tests/libgit2/diff/format_email.c | 8 +- tests/libgit2/diff/index.c | 8 +- tests/libgit2/diff/parse.c | 2 +- tests/libgit2/diff/patchid.c | 2 +- tests/libgit2/diff/rename.c | 2 +- tests/libgit2/diff/stats.c | 2 +- tests/libgit2/diff/workdir.c | 46 +- tests/libgit2/email/create.c | 4 +- tests/libgit2/email/create.c.bak | 386 ---------------- tests/libgit2/fetch/local.c | 4 +- tests/libgit2/fetchhead/nonetwork.c | 40 +- tests/libgit2/filter/bare.c | 4 +- tests/libgit2/graph/ahead_behind.c | 6 +- tests/libgit2/graph/commitgraph.c | 67 ++- tests/libgit2/graph/descendant_of.c | 4 +- tests/libgit2/graph/reachable_from_any.c | 2 +- tests/libgit2/ignore/path.c | 10 +- tests/libgit2/ignore/status.c | 8 +- tests/libgit2/index/add.c | 2 +- tests/libgit2/index/addall.c | 46 ++ tests/libgit2/index/bypath.c | 6 +- tests/libgit2/index/cache.c | 16 +- tests/libgit2/index/conflicts.c | 74 +-- tests/libgit2/index/crlf.c | 19 +- tests/libgit2/index/names.c | 6 +- tests/libgit2/index/read_index.c | 14 +- tests/libgit2/index/rename.c | 2 +- tests/libgit2/index/reuc.c | 70 +-- tests/libgit2/index/tests.c | 16 +- tests/libgit2/iterator/index.c | 10 +- tests/libgit2/iterator/tree.c | 6 +- tests/libgit2/iterator/workdir.c | 4 +- tests/libgit2/merge/driver.c | 6 +- tests/libgit2/merge/files.c | 6 +- tests/libgit2/merge/merge_helpers.c | 10 +- tests/libgit2/merge/merge_helpers.h | 8 +- tests/libgit2/merge/trees/renames.c | 2 +- tests/libgit2/merge/trees/treediff.c | 6 +- tests/libgit2/merge/trees/trivial.c | 4 +- tests/libgit2/merge/workdir/dirty.c | 2 +- tests/libgit2/merge/workdir/setup.c | 110 ++--- tests/libgit2/merge/workdir/simple.c | 18 +- tests/libgit2/merge/workdir/trivial.c | 4 +- tests/libgit2/network/remote/push.c | 5 +- tests/libgit2/network/remote/rename.c | 6 +- tests/libgit2/notes/notes.c | 48 +- tests/libgit2/notes/notesref.c | 2 +- tests/libgit2/object/blob/fromstream.c | 4 +- tests/libgit2/object/cache.c | 14 +- .../libgit2/object/commit/commitstagedfile.c | 6 +- tests/libgit2/object/commit/parse.c | 298 ++++++++++-- tests/libgit2/object/lookup.c | 12 +- tests/libgit2/object/lookup256.c | 153 +++++++ tests/libgit2/object/peel.c | 6 +- tests/libgit2/object/raw/chars.c | 10 +- tests/libgit2/object/raw/compare.c | 38 +- tests/libgit2/object/raw/convert.c | 42 +- tests/libgit2/object/raw/fromstr.c | 15 +- tests/libgit2/object/raw/hash.c | 38 +- tests/libgit2/object/raw/short.c | 8 +- tests/libgit2/object/raw/size.c | 8 +- tests/libgit2/object/raw/write.c | 4 +- tests/libgit2/object/shortid.c | 8 +- tests/libgit2/object/tag/parse.c | 6 +- tests/libgit2/object/tag/peel.c | 2 +- tests/libgit2/object/tag/read.c | 16 +- tests/libgit2/object/tag/write.c | 18 +- tests/libgit2/object/tree/attributes.c | 10 +- tests/libgit2/object/tree/duplicateentries.c | 28 +- tests/libgit2/object/tree/frompath.c | 2 +- tests/libgit2/object/tree/parse.c | 6 +- tests/libgit2/object/tree/read.c | 4 +- tests/libgit2/object/tree/update.c | 62 +-- tests/libgit2/object/tree/walk.c | 6 +- tests/libgit2/object/tree/write.c | 44 +- tests/libgit2/object/validate.c | 158 +++++-- tests/libgit2/odb/alternates.c | 4 +- tests/libgit2/odb/backend/backend_helpers.c | 12 +- tests/libgit2/odb/backend/loose.c | 43 ++ tests/libgit2/odb/backend/mempack.c | 7 +- tests/libgit2/odb/backend/multiple.c | 2 +- tests/libgit2/odb/backend/nobackend.c | 3 +- tests/libgit2/odb/backend/nonrefreshing.c | 4 +- tests/libgit2/odb/backend/refreshing.c | 4 +- tests/libgit2/odb/backend/simple.c | 28 +- tests/libgit2/odb/emptyobjects.c | 6 +- tests/libgit2/odb/foreach.c | 13 +- tests/libgit2/odb/freshen.c | 12 +- tests/libgit2/odb/largefiles.c | 4 +- tests/libgit2/odb/loose.c | 152 ++++++- tests/libgit2/odb/loose_data.h | 387 +++++++++++++++- tests/libgit2/odb/mixed.c | 38 +- tests/libgit2/odb/open.c | 34 ++ tests/libgit2/odb/pack_data_256.h | 154 +++++++ tests/libgit2/odb/pack_data_one256.h | 21 + tests/libgit2/odb/packed.c | 8 +- tests/libgit2/odb/packed256.c | 98 ++++ .../libgit2/odb/{packed_one.c => packedone.c} | 23 +- tests/libgit2/odb/packedone256.c | 78 ++++ tests/libgit2/odb/sorting.c | 13 +- tests/libgit2/online/clone.c | 242 +++++++++- tests/libgit2/online/fetch.c | 4 +- tests/libgit2/online/push.c | 51 ++- tests/libgit2/online/push_util.c | 2 - tests/libgit2/pack/indexer.c | 57 ++- tests/libgit2/pack/midx.c | 8 +- tests/libgit2/pack/packbuilder.c | 17 + tests/libgit2/pack/sharing.c | 2 +- tests/libgit2/patch/parse.c | 2 +- tests/libgit2/perf/helper__perf__do_merge.c | 4 +- tests/libgit2/rebase/abort.c | 12 +- tests/libgit2/rebase/inmemory.c | 10 +- tests/libgit2/rebase/iterator.c | 20 +- tests/libgit2/rebase/merge.c | 30 +- tests/libgit2/rebase/setup.c | 30 +- tests/libgit2/rebase/sign.c | 10 +- tests/libgit2/refs/basic.c | 2 +- tests/libgit2/refs/branches/delete.c | 8 +- tests/libgit2/refs/branches/iterator.c | 2 +- tests/libgit2/refs/create.c | 22 +- tests/libgit2/refs/delete.c | 2 +- tests/libgit2/refs/foreachglob.c | 2 +- tests/libgit2/refs/iterator.c | 3 +- tests/libgit2/refs/lookup.c | 2 +- tests/libgit2/refs/peel.c | 2 +- tests/libgit2/refs/races.c | 24 +- tests/libgit2/refs/read.c | 4 +- tests/libgit2/refs/reflog/drop.c | 4 +- tests/libgit2/refs/reflog/messages.c | 12 +- tests/libgit2/refs/reflog/reflog.c | 24 +- tests/libgit2/refs/reflog/reflog_helpers.c | 26 +- tests/libgit2/refs/revparse.c | 15 +- tests/libgit2/refs/transactions.c | 10 +- tests/libgit2/remote/httpproxy.c | 38 +- tests/libgit2/repo/env.c | 6 +- tests/libgit2/repo/extensions.c | 2 +- tests/libgit2/repo/hashfile.c | 41 +- tests/libgit2/repo/head.c | 2 +- tests/libgit2/repo/init.c | 37 +- tests/libgit2/repo/objectformat.c | 69 +++ tests/libgit2/repo/open.c | 95 +++- tests/libgit2/repo/setters.c | 3 +- tests/libgit2/reset/hard.c | 6 +- tests/libgit2/reset/soft.c | 4 +- tests/libgit2/revert/bare.c | 10 +- tests/libgit2/revert/rename.c | 2 +- tests/libgit2/revert/workdir.c | 40 +- tests/libgit2/revwalk/basic.c | 53 ++- tests/libgit2/revwalk/hidecb.c | 4 +- tests/libgit2/revwalk/mergebase.c | 66 +-- tests/libgit2/revwalk/simplify.c | 4 +- tests/libgit2/stash/save.c | 37 ++ tests/libgit2/status/single.c | 9 +- tests/libgit2/status/submodules.c | 2 +- tests/libgit2/status/worktree.c | 34 +- tests/libgit2/submodule/add.c | 2 +- tests/libgit2/submodule/update.c | 20 + tests/libgit2/transports/smart/packet.c | 41 +- tests/libgit2/win32/forbidden.c | 4 +- tests/libgit2/win32/systemdir.c | 1 - tests/libgit2/worktree/worktree.c | 2 +- tests/resources/namespace.git/COMMIT_EDITMSG | Bin 0 -> 5 bytes tests/resources/namespace.git/HEAD | Bin 0 -> 21 bytes tests/resources/namespace.git/config | Bin 0 -> 137 bytes tests/resources/namespace.git/description | Bin 0 -> 73 bytes tests/resources/namespace.git/index | Bin 0 -> 321 bytes tests/resources/namespace.git/info/exclude | Bin 0 -> 240 bytes tests/resources/namespace.git/logs/HEAD | Bin 0 -> 1533 bytes .../namespace.git/logs/refs/heads/branch | Bin 0 -> 500 bytes .../namespace.git/logs/refs/heads/four | Bin 0 -> 325 bytes .../namespace.git/logs/refs/heads/main | Bin 0 -> 342 bytes .../namespace.git/logs/refs/heads/one | Bin 0 -> 167 bytes .../04/433ff5b52d6ad534fd6288de4a57b81cc12188 | Bin 0 -> 160 bytes .../0a/890bd10328d68f6d85efd2535e3a4c588ee8e6 | Bin 0 -> 54 bytes .../10/fcb1c85bd6b3bc6f43e0a3932ff5859121a84e | Bin 0 -> 54 bytes .../24/bbdca8b223aaa3384d78312f730c58492aa30a | Bin 0 -> 54 bytes .../27/0c611ee72c567bc1b2abec4cbc345bab9f15ba | Bin 0 -> 30 bytes .../2b/df67abb163a4ffb2d7f3f0880c9fe5068ce782 | Bin 0 -> 21 bytes .../3d/669d1b33ec8add4609d8043d025527db4989eb | Bin 0 -> 164 bytes .../42/0d51ce75a87909e29659da2072ffd3d5daf5b7 | Bin 0 -> 128 bytes .../56/26abf0f72e58d7a153368ba57db4c673c0e171 | Bin 0 -> 19 bytes .../56/300b5eae653453102ac1213e921973c066425b | Bin 0 -> 95 bytes .../7e/eaa70d7c5592db920a2e107ce3918bd4c8a425 | Bin 0 -> 168 bytes .../85/10665149157c2bc901848c3e0b746954e9cbd9 | Bin 0 -> 20 bytes .../9e/bfa6bdc9d38075d29d26aa5df89b1cf635b269 | Bin 0 -> 137 bytes .../9e/f15e3c5c0c8c6913936f843ad967cbe5541f0d | Bin 0 -> 121 bytes .../af/5626b4a114abcb82d63db7c8082c3c4756e51b | Bin 0 -> 30 bytes .../af/81e4bd99cbfe6f05a501f1e4c82db2bf803e02 | Bin 0 -> 30 bytes .../bf/d17f429f4e2d121769213171ad57ca2e5173f9 | Bin 0 -> 167 bytes .../ec/947e3dd7a7752d078f1ed0cfde7457b21fef58 | Bin 0 -> 54 bytes .../f7/19efd430d52bcfc8566a43b2eb655688d38871 | Bin 0 -> 19 bytes .../f7/5ba05f340c51065cbea2e1fdbfe5fe13144c97 | Bin 0 -> 30 bytes .../resources/namespace.git/refs/heads/branch | Bin 0 -> 41 bytes tests/resources/namespace.git/refs/heads/main | Bin 0 -> 41 bytes .../refs/namespaces/name1/refs/heads/four | Bin 0 -> 41 bytes .../refs/namespaces/name1/refs/heads/one | Bin 0 -> 41 bytes ...76d752efc71661592db317474a0cf292915f31.idx | Bin 0 -> 1376 bytes ...6d752efc71661592db317474a0cf292915f31.pack | Bin 0 -> 1406 bytes tests/resources/testrepo_256.git/FETCH_HEAD | Bin 0 -> 255 bytes tests/resources/testrepo_256.git/HEAD | Bin 0 -> 23 bytes tests/resources/testrepo_256.git/HEAD_TRACKER | Bin 0 -> 10 bytes tests/resources/testrepo_256.git/config | Bin 0 -> 147 bytes tests/resources/testrepo_256.git/description | Bin 0 -> 73 bytes .../hooks/applypatch-msg.sample | Bin 0 -> 478 bytes .../testrepo_256.git/hooks/commit-msg.sample | Bin 0 -> 896 bytes .../hooks/fsmonitor-watchman.sample | Bin 0 -> 4655 bytes .../testrepo_256.git/hooks/post-update.sample | Bin 0 -> 189 bytes .../hooks/pre-applypatch.sample | Bin 0 -> 424 bytes .../testrepo_256.git/hooks/pre-commit.sample | Bin 0 -> 1643 bytes .../hooks/pre-merge-commit.sample | Bin 0 -> 416 bytes .../testrepo_256.git/hooks/pre-push.sample | Bin 0 -> 1374 bytes .../testrepo_256.git/hooks/pre-rebase.sample | Bin 0 -> 4898 bytes .../testrepo_256.git/hooks/pre-receive.sample | Bin 0 -> 544 bytes .../hooks/prepare-commit-msg.sample | Bin 0 -> 1492 bytes .../hooks/push-to-checkout.sample | Bin 0 -> 2783 bytes .../testrepo_256.git/hooks/update.sample | Bin 0 -> 3650 bytes tests/resources/testrepo_256.git/index | Bin 0 -> 11148 bytes tests/resources/testrepo_256.git/info/exclude | Bin 0 -> 240 bytes tests/resources/testrepo_256.git/logs/HEAD | Bin 0 -> 1497 bytes .../testrepo_256.git/logs/refs/heads/br2 | Bin 0 -> 423 bytes .../testrepo_256.git/logs/refs/heads/master | Bin 0 -> 442 bytes .../testrepo_256.git/logs/refs/heads/not-good | Bin 0 -> 207 bytes .../logs/refs/heads/with-empty-log | Bin .../logs/refs/remotes/origin/HEAD | Bin 0 -> 243 bytes .../logs/refs/remotes/test/master | Bin 0 -> 388 bytes tests/resources/testrepo_256.git/object-idx | Bin 0 -> 180200 bytes ...925bdc34ccdab778bd1d824f5562aaa319c6c8f045 | Bin 0 -> 267 bytes ...6d13866742a9070b56fd0ba9ab8dff828fc36c1f78 | Bin 0 -> 205 bytes ...16acdd727ea9364f7d48c55afed2f7dd889804065b | Bin 0 -> 103 bytes ...fcd19f12cc38faf337d10ec03ef4363d1a86f63750 | Bin 0 -> 21 bytes ...ba8801fe9bda46b66593291f5b9f7cd5f8888af12f | Bin 0 -> 99 bytes ...7e8ddfc9c8c47820fab5615cc04d904989ce800498 | Bin 0 -> 64 bytes ...4acca4ce4e1ea8508dfd77c24cefd461b65cead09e | Bin 0 -> 92 bytes ...da9be93f4afc2279623bb5b36c9194a660b7623c24 | Bin 0 -> 236 bytes ...50334e36a8015a546f0740bea4505e10d81a946f61 | Bin 0 -> 162 bytes ...08d88e14af624bb07fced6390997a0fa6abdad950a | Bin 0 -> 143 bytes ...e50a12b15f26aace3718749624f008bde68670352a | Bin 0 -> 202 bytes ...8644c307e17d0afe29b55f6488398cb59f13feb2f2 | Bin 0 -> 238 bytes ...0efa0433ac0cbd2d44679f68f2df3a9ae7014cf2a8 | Bin 0 -> 19 bytes ...830c2134815a31d9629e6aa9773338fedaab90976b | Bin 0 -> 150 bytes ...f2f30d79af178374166daeceefbf11e2f058d30d60 | Bin 0 -> 21 bytes ...eeca6bfffd9a0fe641784db85de2eb0f57b7553869 | Bin 0 -> 106 bytes ...89aa396d10f71c69e168d5c48ea23de59734ec3ab1 | Bin 0 -> 38 bytes ...917e3db8fde0045ee66305fd5e634b0c793c536a1b | Bin 0 -> 188 bytes ...e3b1e9a7dcda1185436fe141f7749120a303721813 | Bin 0 -> 15 bytes ...31b132e66ef18f564d41efb055804ec1dd28efb3f5 | Bin 0 -> 28 bytes ...2170996ce459d39e3a441e9759b635b0bc4ecc43fd | Bin 0 -> 57 bytes ...8c22b7898baaa0eda205a21cafdcb7e0f94b07bb9b | Bin 0 -> 64 bytes ...44523eb1ddeeef4bce03e35864640b452f84d26848 | Bin 0 -> 251 bytes ...635ab9fbee66d65fe5dda47dd0ac5f01dd69a84c6f | Bin 0 -> 212 bytes ...39b79f964c293db8620d679ea3596673c8a326446e | Bin 0 -> 157 bytes ...492f1bf1fcdf5dca09dab24cf331e05111b4cfc1a3 | Bin 0 -> 24 bytes ...b8f436e3ca0a82b25eddefd237bf5a26a0441c2aa7 | Bin 0 -> 107 bytes ...e660a4d510603c3f36e782a1a32ebd0388db6411ed | Bin 0 -> 181 bytes ...8aeb2c7811556538e7673e4b325307c71685fbf5b6 | Bin 0 -> 108 bytes ...417f9d5ccaf22b877c5a4522b6d1d2b16090ee2f6f | Bin 0 -> 141 bytes ...bccadee60065d8664a9af7648a1455100c4f772e1c | Bin 0 -> 199 bytes ...da9b3179f2419717275e3bfd2055b303489dbbfa47 | Bin 0 -> 63 bytes ...908dc44452ed38911cffa54ccc06076f30a1ffb1bf | Bin 0 -> 108 bytes ...c5d3f23bac1dded688b2bd314cc32b7f157e100724 | Bin 0 -> 190 bytes ...0b96786ebaa9ee6535fb698ec01b5f7a800fa27cbe | Bin 0 -> 137 bytes ...c294c441d08b89b455903c0c14e9b16587fec081f5 | Bin 0 -> 188 bytes ...cddea4259aea6b2961eb0822bd2c0c3f6029030045 | Bin 0 -> 18 bytes ...db7fc3a850e94f8c5ac1d71b9afa365a89005aff54 | Bin 0 -> 221 bytes ...8cc3cf4602c270a369beebc7d0b67238897bbc426b | Bin 0 -> 198 bytes ...24297e83e4a285f58bf5eabb1db270351388603c95 | Bin 0 -> 244 bytes ...ea61f40c14bdfc5b101b60fde4f44b58dd06667640 | Bin 0 -> 63 bytes ...3fdeed5502fd56b182af01b7740d297a24459333c5 | Bin 0 -> 26 bytes ...a3497ade7f62d2cd818bf388775cfa721de4068ebd | Bin 0 -> 54 bytes ...4ebf05e11d9c591b04cfdaff7cc860310356d71827 | Bin 0 -> 199 bytes ...82c5c09c22053675e2db24ea6b4b28cc75e9c10890 | Bin 0 -> 37 bytes ...a7ab8c68929bdc91b69ad54ef94979b93eba3f6022 | Bin 0 -> 190 bytes ...157ee4aad97814279fe500340eb3465797cbd3be23 | Bin 0 -> 23 bytes ...444b12c412210e9689c17e51bfc318ce4bb4360f19 | Bin 0 -> 57 bytes ...aaa96359f304c3dc97e95f336269ed474ea846ada5 | Bin 0 -> 198 bytes ...411d955520e0375fcbbcc14b7636a70f7536c32ef6 | Bin 0 -> 148 bytes ...787c5e94ba024ac9a4f763cb1d9bfd8e63aa7f7269 | Bin 0 -> 182 bytes ...621f5a228cb33dc84192980ca426cf9ab2a48cb9f0 | Bin 0 -> 187 bytes ...abfa899655d1b00e6529101a40d42f6acb059dff9f | Bin 0 -> 21 bytes ...3d137b654c602721c469c1b0a58e7e95647a9cf1c0 | Bin 0 -> 163 bytes ...8e201abb820a414de03eb63c065b06a2ab37d3f5ca | Bin 0 -> 171 bytes ...d3d4a80ced03101555e1fd8913b3544026c0717d4f | Bin 0 -> 181 bytes ...a5d92b78e54493fdaa78f72268d4cc69b61d5feee1 | Bin 0 -> 21 bytes ...55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736 | Bin 0 -> 157 bytes ...441f0b3f387faeddde1b37d0ad2f3f6a63f5327978 | Bin 0 -> 192 bytes ...24c75107423d5773066922ea5e55eaeb6490979562 | Bin 0 -> 157 bytes ...6e7643653c03e7f91faa27b767e3eb8225f0f6.idx | Bin 0 -> 1336 bytes ...e7643653c03e7f91faa27b767e3eb8225f0f6.pack | Bin 0 -> 569 bytes ...791b9b270067124b2609019b74f33f256f33fa.idx | Bin 0 -> 66216 bytes ...91b9b270067124b2609019b74f33f256f33fa.pack | Bin 0 -> 562646 bytes ...80b24ee981cf102db76764c383f9b87935d0d3.idx | Bin 0 -> 1336 bytes ...0b24ee981cf102db76764c383f9b87935d0d3.pack | Bin 0 -> 612 bytes tests/resources/testrepo_256.git/packed-refs | Bin 0 -> 204 bytes .../refs/blobs/annotated_tag_to_blob | Bin 0 -> 65 bytes .../resources/testrepo_256.git/refs/heads/br2 | Bin 0 -> 65 bytes .../testrepo_256.git/refs/heads/cannot-fetch | Bin 0 -> 65 bytes .../testrepo_256.git/refs/heads/chomped | Bin 0 -> 65 bytes .../testrepo_256.git/refs/heads/haacked | Bin 0 -> 65 bytes .../testrepo_256.git/refs/heads/master | Bin 0 -> 65 bytes .../testrepo_256.git/refs/heads/not-good | Bin 0 -> 65 bytes .../testrepo_256.git/refs/heads/packed-test | Bin 0 -> 65 bytes .../testrepo_256.git/refs/heads/subtrees | Bin 0 -> 65 bytes .../testrepo_256.git/refs/heads/test | Bin 0 -> 65 bytes .../testrepo_256.git/refs/heads/track-local | Bin 0 -> 65 bytes .../testrepo_256.git/refs/heads/trailing | Bin 0 -> 65 bytes .../refs/heads/with-empty-log | Bin 0 -> 65 bytes .../testrepo_256.git/refs/notes/fanout | Bin 0 -> 65 bytes .../testrepo_256.git/refs/remotes/test/master | Bin 0 -> 65 bytes .../refs/tags/annotated_tag_to_blob | Bin 0 -> 65 bytes .../testrepo_256.git/refs/tags/e90810b | Bin 0 -> 65 bytes .../testrepo_256.git/refs/tags/hard_tag | Bin 0 -> 65 bytes .../testrepo_256.git/refs/tags/point_to_blob | Bin 0 -> 65 bytes .../testrepo_256.git/refs/tags/taggerless | Bin 0 -> 65 bytes .../resources/testrepo_256.git/refs/tags/test | Bin 0 -> 65 bytes .../testrepo_256.git/refs/tags/wrapped_tag | Bin 0 -> 65 bytes tests/util/path.c | 6 +- .../{libgit2/network => util}/url/joinpath.c | 16 +- tests/{libgit2/network => util}/url/parse.c | 312 +++++++++++-- tests/{libgit2/network => util}/url/pattern.c | 4 +- .../{libgit2/network => util}/url/redirect.c | 26 +- tests/{libgit2/network => util}/url/scp.c | 50 +- tests/{libgit2/network => util}/url/valid.c | 2 +- 518 files changed, 8614 insertions(+), 3567 deletions(-) create mode 100755 ci/setup-win32-build.sh create mode 100644 cmake/ExperimentalFeatures.cmake create mode 100644 include/git2/experimental.h create mode 100644 src/libgit2/experimental.h.in create mode 100644 src/libgit2/strarray.h rename src/{features.h.in => util/git2_features.h.in} (100%) delete mode 100644 src/util/win32/findfile.c delete mode 100644 src/util/win32/findfile.h create mode 100644 tests/libgit2/config/find.c delete mode 100644 tests/libgit2/email/create.c.bak create mode 100644 tests/libgit2/object/lookup256.c create mode 100644 tests/libgit2/odb/backend/loose.c create mode 100644 tests/libgit2/odb/open.c create mode 100644 tests/libgit2/odb/pack_data_256.h create mode 100644 tests/libgit2/odb/pack_data_one256.h create mode 100644 tests/libgit2/odb/packed256.c rename tests/libgit2/odb/{packed_one.c => packedone.c} (55%) create mode 100644 tests/libgit2/odb/packedone256.c create mode 100644 tests/libgit2/repo/objectformat.c create mode 100644 tests/resources/namespace.git/COMMIT_EDITMSG create mode 100644 tests/resources/namespace.git/HEAD create mode 100644 tests/resources/namespace.git/config create mode 100644 tests/resources/namespace.git/description create mode 100644 tests/resources/namespace.git/index create mode 100644 tests/resources/namespace.git/info/exclude create mode 100644 tests/resources/namespace.git/logs/HEAD create mode 100644 tests/resources/namespace.git/logs/refs/heads/branch create mode 100644 tests/resources/namespace.git/logs/refs/heads/four create mode 100644 tests/resources/namespace.git/logs/refs/heads/main create mode 100644 tests/resources/namespace.git/logs/refs/heads/one create mode 100644 tests/resources/namespace.git/objects/04/433ff5b52d6ad534fd6288de4a57b81cc12188 create mode 100644 tests/resources/namespace.git/objects/0a/890bd10328d68f6d85efd2535e3a4c588ee8e6 create mode 100644 tests/resources/namespace.git/objects/10/fcb1c85bd6b3bc6f43e0a3932ff5859121a84e create mode 100644 tests/resources/namespace.git/objects/24/bbdca8b223aaa3384d78312f730c58492aa30a create mode 100644 tests/resources/namespace.git/objects/27/0c611ee72c567bc1b2abec4cbc345bab9f15ba create mode 100644 tests/resources/namespace.git/objects/2b/df67abb163a4ffb2d7f3f0880c9fe5068ce782 create mode 100644 tests/resources/namespace.git/objects/3d/669d1b33ec8add4609d8043d025527db4989eb create mode 100644 tests/resources/namespace.git/objects/42/0d51ce75a87909e29659da2072ffd3d5daf5b7 create mode 100644 tests/resources/namespace.git/objects/56/26abf0f72e58d7a153368ba57db4c673c0e171 create mode 100644 tests/resources/namespace.git/objects/56/300b5eae653453102ac1213e921973c066425b create mode 100644 tests/resources/namespace.git/objects/7e/eaa70d7c5592db920a2e107ce3918bd4c8a425 create mode 100644 tests/resources/namespace.git/objects/85/10665149157c2bc901848c3e0b746954e9cbd9 create mode 100644 tests/resources/namespace.git/objects/9e/bfa6bdc9d38075d29d26aa5df89b1cf635b269 create mode 100644 tests/resources/namespace.git/objects/9e/f15e3c5c0c8c6913936f843ad967cbe5541f0d create mode 100644 tests/resources/namespace.git/objects/af/5626b4a114abcb82d63db7c8082c3c4756e51b create mode 100644 tests/resources/namespace.git/objects/af/81e4bd99cbfe6f05a501f1e4c82db2bf803e02 create mode 100644 tests/resources/namespace.git/objects/bf/d17f429f4e2d121769213171ad57ca2e5173f9 create mode 100644 tests/resources/namespace.git/objects/ec/947e3dd7a7752d078f1ed0cfde7457b21fef58 create mode 100644 tests/resources/namespace.git/objects/f7/19efd430d52bcfc8566a43b2eb655688d38871 create mode 100644 tests/resources/namespace.git/objects/f7/5ba05f340c51065cbea2e1fdbfe5fe13144c97 create mode 100644 tests/resources/namespace.git/refs/heads/branch create mode 100644 tests/resources/namespace.git/refs/heads/main create mode 100644 tests/resources/namespace.git/refs/namespaces/name1/refs/heads/four create mode 100644 tests/resources/namespace.git/refs/namespaces/name1/refs/heads/one create mode 100644 tests/resources/packfile-sha256/pack-b4a043c0ec5e079e8ac67d823776d752efc71661592db317474a0cf292915f31.idx create mode 100644 tests/resources/packfile-sha256/pack-b4a043c0ec5e079e8ac67d823776d752efc71661592db317474a0cf292915f31.pack create mode 100644 tests/resources/testrepo_256.git/FETCH_HEAD create mode 100644 tests/resources/testrepo_256.git/HEAD create mode 100644 tests/resources/testrepo_256.git/HEAD_TRACKER create mode 100644 tests/resources/testrepo_256.git/config create mode 100644 tests/resources/testrepo_256.git/description create mode 100755 tests/resources/testrepo_256.git/hooks/applypatch-msg.sample create mode 100755 tests/resources/testrepo_256.git/hooks/commit-msg.sample create mode 100755 tests/resources/testrepo_256.git/hooks/fsmonitor-watchman.sample create mode 100755 tests/resources/testrepo_256.git/hooks/post-update.sample create mode 100755 tests/resources/testrepo_256.git/hooks/pre-applypatch.sample create mode 100755 tests/resources/testrepo_256.git/hooks/pre-commit.sample create mode 100755 tests/resources/testrepo_256.git/hooks/pre-merge-commit.sample create mode 100755 tests/resources/testrepo_256.git/hooks/pre-push.sample create mode 100755 tests/resources/testrepo_256.git/hooks/pre-rebase.sample create mode 100755 tests/resources/testrepo_256.git/hooks/pre-receive.sample create mode 100755 tests/resources/testrepo_256.git/hooks/prepare-commit-msg.sample create mode 100755 tests/resources/testrepo_256.git/hooks/push-to-checkout.sample create mode 100755 tests/resources/testrepo_256.git/hooks/update.sample create mode 100644 tests/resources/testrepo_256.git/index create mode 100644 tests/resources/testrepo_256.git/info/exclude create mode 100644 tests/resources/testrepo_256.git/logs/HEAD create mode 100644 tests/resources/testrepo_256.git/logs/refs/heads/br2 create mode 100644 tests/resources/testrepo_256.git/logs/refs/heads/master create mode 100644 tests/resources/testrepo_256.git/logs/refs/heads/not-good create mode 100644 tests/resources/testrepo_256.git/logs/refs/heads/with-empty-log create mode 100644 tests/resources/testrepo_256.git/logs/refs/remotes/origin/HEAD create mode 100644 tests/resources/testrepo_256.git/logs/refs/remotes/test/master create mode 100644 tests/resources/testrepo_256.git/object-idx create mode 100644 tests/resources/testrepo_256.git/objects/00/404e6179d86039bbc01a925bdc34ccdab778bd1d824f5562aaa319c6c8f045 create mode 100644 tests/resources/testrepo_256.git/objects/01/18010feb81fe41b9df646d13866742a9070b56fd0ba9ab8dff828fc36c1f78 create mode 100644 tests/resources/testrepo_256.git/objects/02/df938cfb169b0b6ba0dd16acdd727ea9364f7d48c55afed2f7dd889804065b create mode 100644 tests/resources/testrepo_256.git/objects/05/f7b70a01b0ade8afa5a5fcd19f12cc38faf337d10ec03ef4363d1a86f63750 create mode 100644 tests/resources/testrepo_256.git/objects/14/bd335f9d7188c778d44eba8801fe9bda46b66593291f5b9f7cd5f8888af12f create mode 100644 tests/resources/testrepo_256.git/objects/17/9496410f66032c03bd2b7e8ddfc9c8c47820fab5615cc04d904989ce800498 create mode 100644 tests/resources/testrepo_256.git/objects/19/0a1349522cc11f8682e34acca4ce4e1ea8508dfd77c24cefd461b65cead09e create mode 100644 tests/resources/testrepo_256.git/objects/1b/4b74772bd83ff28bf44cda9be93f4afc2279623bb5b36c9194a660b7623c24 create mode 100644 tests/resources/testrepo_256.git/objects/21/e1e1ebe45b2c1ef79ab050334e36a8015a546f0740bea4505e10d81a946f61 create mode 100644 tests/resources/testrepo_256.git/objects/23/8a501cf11a036f2f248008d88e14af624bb07fced6390997a0fa6abdad950a create mode 100644 tests/resources/testrepo_256.git/objects/26/149bf1ac4612f24b532ae50a12b15f26aace3718749624f008bde68670352a create mode 100644 tests/resources/testrepo_256.git/objects/2d/b6069c27ca4c08b784048644c307e17d0afe29b55f6488398cb59f13feb2f2 create mode 100644 tests/resources/testrepo_256.git/objects/33/e415b835a670bb5c3c760efa0433ac0cbd2d44679f68f2df3a9ae7014cf2a8 create mode 100644 tests/resources/testrepo_256.git/objects/34/f79ad1c813b93d2ee11c830c2134815a31d9629e6aa9773338fedaab90976b create mode 100644 tests/resources/testrepo_256.git/objects/36/eac24505d4c4405864ccf2f30d79af178374166daeceefbf11e2f058d30d60 create mode 100644 tests/resources/testrepo_256.git/objects/39/bf1ac28cc3f8432ba7cfeeca6bfffd9a0fe641784db85de2eb0f57b7553869 create mode 100644 tests/resources/testrepo_256.git/objects/3b/58565ee067f13349cd4f89aa396d10f71c69e168d5c48ea23de59734ec3ab1 create mode 100644 tests/resources/testrepo_256.git/objects/43/e084a4599ca42c476919917e3db8fde0045ee66305fd5e634b0c793c536a1b create mode 100644 tests/resources/testrepo_256.git/objects/47/3a0f4c3be8a93681a267e3b1e9a7dcda1185436fe141f7749120a303721813 create mode 100644 tests/resources/testrepo_256.git/objects/4b/c142808884e472ee6cc331b132e66ef18f564d41efb055804ec1dd28efb3f5 create mode 100644 tests/resources/testrepo_256.git/objects/4d/f8ed86acaac5dc82b5652170996ce459d39e3a441e9759b635b0bc4ecc43fd create mode 100644 tests/resources/testrepo_256.git/objects/5a/2d5699fea33657b42ba98c22b7898baaa0eda205a21cafdcb7e0f94b07bb9b create mode 100644 tests/resources/testrepo_256.git/objects/5c/a8959deb2b8327458e0344523eb1ddeeef4bce03e35864640b452f84d26848 create mode 100644 tests/resources/testrepo_256.git/objects/5d/bb1fff5c0094b31b25b4635ab9fbee66d65fe5dda47dd0ac5f01dd69a84c6f create mode 100644 tests/resources/testrepo_256.git/objects/61/489e9e831f1d9001084d39b79f964c293db8620d679ea3596673c8a326446e create mode 100644 tests/resources/testrepo_256.git/objects/6d/5fd291bb0f67444e99ab492f1bf1fcdf5dca09dab24cf331e05111b4cfc1a3 create mode 100644 tests/resources/testrepo_256.git/objects/70/30f925768d9beb65654ab8f436e3ca0a82b25eddefd237bf5a26a0441c2aa7 create mode 100644 tests/resources/testrepo_256.git/objects/73/8ff86401dbc5af692c83e660a4d510603c3f36e782a1a32ebd0388db6411ed create mode 100644 tests/resources/testrepo_256.git/objects/73/b4f3c4f3182e6c8dd2c98aeb2c7811556538e7673e4b325307c71685fbf5b6 create mode 100644 tests/resources/testrepo_256.git/objects/7e/4633ae1b0e83503dbea4417f9d5ccaf22b877c5a4522b6d1d2b16090ee2f6f create mode 100644 tests/resources/testrepo_256.git/objects/7e/9424c06052ca33bfc599bccadee60065d8664a9af7648a1455100c4f772e1c create mode 100644 tests/resources/testrepo_256.git/objects/80/91b686de8bf697ef632dda9b3179f2419717275e3bfd2055b303489dbbfa47 create mode 100644 tests/resources/testrepo_256.git/objects/81/55958bbda08eed88c8ac908dc44452ed38911cffa54ccc06076f30a1ffb1bf create mode 100644 tests/resources/testrepo_256.git/objects/90/1505c3355518bee35475c5d3f23bac1dded688b2bd314cc32b7f157e100724 create mode 100644 tests/resources/testrepo_256.git/objects/93/1093620e5f050e2127fb0b96786ebaa9ee6535fb698ec01b5f7a800fa27cbe create mode 100644 tests/resources/testrepo_256.git/objects/94/ed253efa9e86fc636805c294c441d08b89b455903c0c14e9b16587fec081f5 create mode 100644 tests/resources/testrepo_256.git/objects/96/c18f0297e38d01f4b2dacddea4259aea6b2961eb0822bd2c0c3f6029030045 create mode 100644 tests/resources/testrepo_256.git/objects/9c/cfa556cd7f73b426a7bedb7fc3a850e94f8c5ac1d71b9afa365a89005aff54 create mode 100644 tests/resources/testrepo_256.git/objects/9d/aab17c25f647d652c72c8cc3cf4602c270a369beebc7d0b67238897bbc426b create mode 100644 tests/resources/testrepo_256.git/objects/a4/813ef6708e6011e8187224297e83e4a285f58bf5eabb1db270351388603c95 create mode 100644 tests/resources/testrepo_256.git/objects/ab/ee32b3339d1566d75613ea61f40c14bdfc5b101b60fde4f44b58dd06667640 create mode 100644 tests/resources/testrepo_256.git/objects/ae/a29dc305d40e362df25c3fdeed5502fd56b182af01b7740d297a24459333c5 create mode 100644 tests/resources/testrepo_256.git/objects/b1/95873b48c824d995c974a3497ade7f62d2cd818bf388775cfa721de4068ebd create mode 100644 tests/resources/testrepo_256.git/objects/b2/1c8c27a05a3f0bf9f0f44ebf05e11d9c591b04cfdaff7cc860310356d71827 create mode 100644 tests/resources/testrepo_256.git/objects/b6/1b940a8cd979a32e005682c5c09c22053675e2db24ea6b4b28cc75e9c10890 create mode 100644 tests/resources/testrepo_256.git/objects/b8/3624f6ac0995273c0034a7ab8c68929bdc91b69ad54ef94979b93eba3f6022 create mode 100644 tests/resources/testrepo_256.git/objects/bd/f2066a28e11603a1af04157ee4aad97814279fe500340eb3465797cbd3be23 create mode 100644 tests/resources/testrepo_256.git/objects/bf/a3b3b9a161d354e2254a444b12c412210e9689c17e51bfc318ce4bb4360f19 create mode 100644 tests/resources/testrepo_256.git/objects/bf/cc4074ac517ed24d61b0aaa96359f304c3dc97e95f336269ed474ea846ada5 create mode 100644 tests/resources/testrepo_256.git/objects/c2/58f010a08328a29cde33411d955520e0375fcbbcc14b7636a70f7536c32ef6 create mode 100644 tests/resources/testrepo_256.git/objects/ca/31f7336e882a233a2943787c5e94ba024ac9a4f763cb1d9bfd8e63aa7f7269 create mode 100644 tests/resources/testrepo_256.git/objects/cb/282e7c15fd8aeb2265cd621f5a228cb33dc84192980ca426cf9ab2a48cb9f0 create mode 100644 tests/resources/testrepo_256.git/objects/cc/b5a03da85607c230d111abfa899655d1b00e6529101a40d42f6acb059dff9f create mode 100644 tests/resources/testrepo_256.git/objects/cf/84e5be57f8d5d51f136d3d137b654c602721c469c1b0a58e7e95647a9cf1c0 create mode 100644 tests/resources/testrepo_256.git/objects/d8/8b60d2641df3656381dc8e201abb820a414de03eb63c065b06a2ab37d3f5ca create mode 100644 tests/resources/testrepo_256.git/objects/de/caff3051968d1f3a2defd3d4a80ced03101555e1fd8913b3544026c0717d4f create mode 100644 tests/resources/testrepo_256.git/objects/eb/ead5965196dfaeab52b1a5d92b78e54493fdaa78f72268d4cc69b61d5feee1 create mode 100644 tests/resources/testrepo_256.git/objects/f2/a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736 create mode 100644 tests/resources/testrepo_256.git/objects/f2/c8da1a7c2eb49ff25c47441f0b3f387faeddde1b37d0ad2f3f6a63f5327978 create mode 100644 tests/resources/testrepo_256.git/objects/f3/1459efb9367c5a19c9dd24c75107423d5773066922ea5e55eaeb6490979562 create mode 100644 tests/resources/testrepo_256.git/objects/pack/pack-b87f1f214098b19ce092afb9ef6e7643653c03e7f91faa27b767e3eb8225f0f6.idx create mode 100644 tests/resources/testrepo_256.git/objects/pack/pack-b87f1f214098b19ce092afb9ef6e7643653c03e7f91faa27b767e3eb8225f0f6.pack create mode 100644 tests/resources/testrepo_256.git/objects/pack/pack-e2f07f30db7e480ea84a0e64ee791b9b270067124b2609019b74f33f256f33fa.idx create mode 100644 tests/resources/testrepo_256.git/objects/pack/pack-e2f07f30db7e480ea84a0e64ee791b9b270067124b2609019b74f33f256f33fa.pack create mode 100644 tests/resources/testrepo_256.git/objects/pack/pack-f72bbfa35af982c2a60735152c80b24ee981cf102db76764c383f9b87935d0d3.idx create mode 100644 tests/resources/testrepo_256.git/objects/pack/pack-f72bbfa35af982c2a60735152c80b24ee981cf102db76764c383f9b87935d0d3.pack create mode 100644 tests/resources/testrepo_256.git/packed-refs create mode 100644 tests/resources/testrepo_256.git/refs/blobs/annotated_tag_to_blob create mode 100644 tests/resources/testrepo_256.git/refs/heads/br2 create mode 100644 tests/resources/testrepo_256.git/refs/heads/cannot-fetch create mode 100644 tests/resources/testrepo_256.git/refs/heads/chomped create mode 100644 tests/resources/testrepo_256.git/refs/heads/haacked create mode 100644 tests/resources/testrepo_256.git/refs/heads/master create mode 100644 tests/resources/testrepo_256.git/refs/heads/not-good create mode 100644 tests/resources/testrepo_256.git/refs/heads/packed-test create mode 100644 tests/resources/testrepo_256.git/refs/heads/subtrees create mode 100644 tests/resources/testrepo_256.git/refs/heads/test create mode 100644 tests/resources/testrepo_256.git/refs/heads/track-local create mode 100644 tests/resources/testrepo_256.git/refs/heads/trailing create mode 100644 tests/resources/testrepo_256.git/refs/heads/with-empty-log create mode 100644 tests/resources/testrepo_256.git/refs/notes/fanout create mode 100644 tests/resources/testrepo_256.git/refs/remotes/test/master create mode 100644 tests/resources/testrepo_256.git/refs/tags/annotated_tag_to_blob create mode 100644 tests/resources/testrepo_256.git/refs/tags/e90810b create mode 100644 tests/resources/testrepo_256.git/refs/tags/hard_tag create mode 100644 tests/resources/testrepo_256.git/refs/tags/point_to_blob create mode 100644 tests/resources/testrepo_256.git/refs/tags/taggerless create mode 100644 tests/resources/testrepo_256.git/refs/tags/test create mode 100644 tests/resources/testrepo_256.git/refs/tags/wrapped_tag rename tests/{libgit2/network => util}/url/joinpath.c (93%) rename tests/{libgit2/network => util}/url/parse.c (64%) rename tests/{libgit2/network => util}/url/pattern.c (97%) rename tests/{libgit2/network => util}/url/redirect.c (84%) rename tests/{libgit2/network => util}/url/scp.c (89%) rename tests/{libgit2/network => util}/url/valid.c (94%) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 285c273b1..bf2167464 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -27,7 +27,7 @@ jobs: os: ubuntu-latest setup-script: ubuntu - name: "macOS" - os: macos-10.15 + os: macos-11 env: CC: clang CMAKE_OPTIONS: -DREGEX_BACKEND=regcomp_l -DDEPRECATE_HARD=ON -DUSE_GSSAPI=ON -DBUILD_TESTS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_CLI=ON -DCMAKE_BUILD_TYPE=Release @@ -50,7 +50,7 @@ jobs: runs-on: ${{ matrix.platform.os }} steps: - name: Check out repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: path: source fetch-depth: 0 @@ -66,9 +66,9 @@ jobs: - name: Benchmark run: | if [[ "$(uname -s)" == MINGW* ]]; then - GIT2_CLI="$(cygpath -w $(pwd))\\build\\Release\\git2_cli" + GIT2_CLI="$(cygpath -w $(pwd))\\build\\Release\\git2" else - GIT2_CLI="$(pwd)/build/git2_cli" + GIT2_CLI="$(pwd)/build/git2" fi mkdir benchmark && cd benchmark diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bcad84b8b..0eedab87a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -48,7 +48,7 @@ jobs: name: "Create container: ${{ matrix.container.name }}" steps: - name: Check out repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: path: source fetch-depth: 0 @@ -120,52 +120,9 @@ jobs: CMAKE_OPTIONS: -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON CMAKE_GENERATOR: Ninja os: ubuntu-latest - - name: "Linux (MemorySanitizer)" - id: memorysanitizer - container: - name: focal - env: - CC: clang-10 - CFLAGS: -fsanitize=memory -fsanitize-memory-track-origins=2 -fsanitize-blacklist=/home/libgit2/source/script/sanitizers.supp -fno-optimize-sibling-calls -fno-omit-frame-pointer - CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=/usr/local/msan -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON -DUSE_SSH=ON - CMAKE_GENERATOR: Ninja - SKIP_SSH_TESTS: true - SKIP_NEGOTIATE_TESTS: true - ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10 - UBSAN_OPTIONS: print_stacktrace=1 - os: ubuntu-latest - - name: "Linux (UndefinedBehaviorSanitizer)" - id: ubsanitizer - container: - name: focal - env: - CC: clang-10 - CFLAGS: -fsanitize=undefined,nullability -fno-sanitize-recover=undefined,nullability -fsanitize-blacklist=/home/libgit2/source/script/sanitizers.supp -fno-optimize-sibling-calls -fno-omit-frame-pointer - CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=/usr/local -DUSE_HTTPS=OpenSSL -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON -DUSE_SSH=ON - CMAKE_GENERATOR: Ninja - SKIP_SSH_TESTS: true - SKIP_NEGOTIATE_TESTS: true - ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10 - UBSAN_OPTIONS: print_stacktrace=1 - os: ubuntu-latest - - name: "Linux (ThreadSanitizer)" - id: threadsanitizer - container: - name: focal - env: - CC: clang-10 - CFLAGS: -fsanitize=thread -fno-optimize-sibling-calls -fno-omit-frame-pointer - CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=/usr/local -DUSE_HTTPS=OpenSSL -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON -DUSE_SSH=ON - CMAKE_GENERATOR: Ninja - SKIP_SSH_TESTS: true - SKIP_NEGOTIATE_TESTS: true - ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10 - UBSAN_OPTIONS: print_stacktrace=1 - TSAN_OPTIONS: suppressions=/home/libgit2/source/script/thread-sanitizer.supp second_deadlock_stack=1 - os: ubuntu-latest - name: "macOS" id: macos - os: macos-10.15 + os: macos-11 env: CC: clang CMAKE_OPTIONS: -DREGEX_BACKEND=regcomp_l -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=leaks -DUSE_GSSAPI=ON @@ -176,19 +133,25 @@ jobs: - name: "Windows (amd64, Visual Studio)" id: windows-amd64-vs os: windows-2019 + setup-script: win32 env: ARCH: amd64 CMAKE_GENERATOR: Visual Studio 16 2019 - CMAKE_OPTIONS: -A x64 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON + CMAKE_OPTIONS: -A x64 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON -DUSE_SSH=ON -DCMAKE_PREFIX_PATH=D:\Temp\libssh2 + BUILD_PATH: C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Program Files (x86)\CMake\bin;D:\Temp\libssh2\bin + BUILD_TEMP: D:\Temp SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true - name: "Windows (x86, Visual Studio)" id: windows-x86-vs os: windows-2019 + setup-script: win32 env: ARCH: x86 CMAKE_GENERATOR: Visual Studio 16 2019 - CMAKE_OPTIONS: -A Win32 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON -DUSE_SHA1=HTTPS -DUSE_BUNDLED_ZLIB=ON + CMAKE_OPTIONS: -A Win32 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON -DUSE_SHA1=HTTPS -DUSE_BUNDLED_ZLIB=ON -DUSE_SSH=ON -DCMAKE_PREFIX_PATH=D:\Temp\libssh2 + BUILD_PATH: C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Program Files (x86)\CMake\bin;D:\Temp\libssh2\bin + BUILD_TEMP: D:\Temp SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true - name: "Windows (amd64, mingw)" @@ -215,13 +178,88 @@ jobs: BUILD_PATH: D:\Temp\mingw32\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Program Files (x86)\CMake\bin SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true + + # Sanitizers + - name: "Sanitizer (Memory)" + id: memorysanitizer + container: + name: focal + env: + CC: clang-10 + CFLAGS: -fsanitize=memory -fsanitize-memory-track-origins=2 -fsanitize-blacklist=/home/libgit2/source/script/sanitizers.supp -fno-optimize-sibling-calls -fno-omit-frame-pointer + CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=/usr/local/msan -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON -DUSE_SSH=ON + CMAKE_GENERATOR: Ninja + SKIP_SSH_TESTS: true + SKIP_NEGOTIATE_TESTS: true + ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10 + UBSAN_OPTIONS: print_stacktrace=1 + os: ubuntu-latest + - name: "Sanitizer (UndefinedBehavior)" + id: ubsanitizer + container: + name: focal + env: + CC: clang-10 + CFLAGS: -fsanitize=undefined,nullability -fno-sanitize-recover=undefined,nullability -fsanitize-blacklist=/home/libgit2/source/script/sanitizers.supp -fno-optimize-sibling-calls -fno-omit-frame-pointer + CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=/usr/local -DUSE_HTTPS=OpenSSL -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON -DUSE_SSH=ON + CMAKE_GENERATOR: Ninja + SKIP_SSH_TESTS: true + SKIP_NEGOTIATE_TESTS: true + ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10 + UBSAN_OPTIONS: print_stacktrace=1 + os: ubuntu-latest + - name: "Sanitizer (Thread)" + id: threadsanitizer + container: + name: focal + env: + CC: clang-10 + CFLAGS: -fsanitize=thread -fno-optimize-sibling-calls -fno-omit-frame-pointer + CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=/usr/local -DUSE_HTTPS=OpenSSL -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON -DUSE_SSH=ON + CMAKE_GENERATOR: Ninja + SKIP_SSH_TESTS: true + SKIP_NEGOTIATE_TESTS: true + ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10 + UBSAN_OPTIONS: print_stacktrace=1 + TSAN_OPTIONS: suppressions=/home/libgit2/source/script/thread-sanitizer.supp second_deadlock_stack=1 + os: ubuntu-latest + + # Experimental: SHA256 support + - name: "Linux (SHA256, Xenial, Clang, OpenSSL)" + id: xenial-clang-openssl + container: + name: xenial + env: + CC: clang + CMAKE_GENERATOR: Ninja + CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON -DEXPERIMENTAL_SHA256=ON + os: ubuntu-latest + - name: "macOS (SHA256)" + id: macos + os: macos-11 + env: + CC: clang + CMAKE_OPTIONS: -DREGEX_BACKEND=regcomp_l -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=leaks -DUSE_GSSAPI=ON -DEXPERIMENTAL_SHA256=ON + PKG_CONFIG_PATH: /usr/local/opt/openssl/lib/pkgconfig + SKIP_SSH_TESTS: true + SKIP_NEGOTIATE_TESTS: true + setup-script: osx + - name: "Windows (SHA256, amd64, Visual Studio)" + id: windows-amd64-vs + os: windows-2019 + env: + ARCH: amd64 + CMAKE_GENERATOR: Visual Studio 16 2019 + CMAKE_OPTIONS: -A x64 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON -DEXPERIMENTAL_SHA256=ON + SKIP_SSH_TESTS: true + SKIP_NEGOTIATE_TESTS: true fail-fast: false env: ${{ matrix.platform.env }} runs-on: ${{ matrix.platform.os }} name: "Build: ${{ matrix.platform.name }}" steps: - name: Check out repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: path: source fetch-depth: 0 @@ -251,6 +289,10 @@ jobs: - name: Build and test run: | export GITTEST_NEGOTIATE_PASSWORD="${{ secrets.GITTEST_NEGOTIATE_PASSWORD }}" + export GITTEST_GITHUB_SSH_KEY="${{ secrets.GITTEST_GITHUB_SSH_KEY }}" + export GITTEST_GITHUB_SSH_PUBKEY="${{ secrets.GITTEST_GITHUB_SSH_PUBKEY }}" + export GITTEST_GITHUB_SSH_PASSPHRASE="${{ secrets.GITTEST_GITHUB_SSH_PASSPHRASE }}" + export GITTEST_GITHUB_SSH_REMOTE_HOSTKEY="${{ secrets.GITTEST_GITHUB_SSH_REMOTE_HOSTKEY }}" if [ -n "${{ matrix.platform.container.name }}" ]; then mkdir build @@ -291,12 +333,13 @@ jobs: test_results: name: Test results needs: [ build ] + if: always() runs-on: ubuntu-latest steps: - name: Download test results uses: actions/download-artifact@v3 - name: Generate test summary - uses: test-summary/action@v1 + uses: test-summary/action@v2 with: paths: 'test-results-*/*.xml' @@ -313,7 +356,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: path: source fetch-depth: 0 @@ -332,7 +375,7 @@ jobs: cm doc api.docurium git checkout gh-pages zip --exclude .git/\* --exclude .gitignore --exclude .gitattributes -r api-documentation.zip . - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 name: Upload artifact with: name: api-documentation diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 856da28a3..5a0b7d12b 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -154,7 +154,7 @@ jobs: SKIP_SSH_TESTS: true os: ubuntu-latest - name: "macOS" - os: macos-10.15 + os: macos-11 env: CC: clang CMAKE_OPTIONS: -DREGEX_BACKEND=regcomp_l -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=leaks -DUSE_GSSAPI=ON @@ -265,13 +265,43 @@ jobs: RUN_INVASIVE_TESTS: true SKIP_PROXY_TESTS: true os: ubuntu-latest + + # Experimental: SHA256 support + - name: "Linux (SHA256, Xenial, Clang, OpenSSL)" + id: xenial-clang-openssl + container: + name: xenial + env: + CC: clang + CMAKE_GENERATOR: Ninja + CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON + os: ubuntu-latest + - name: "macOS (SHA256)" + id: macos + os: macos-10.15 + env: + CC: clang + CMAKE_OPTIONS: -DREGEX_BACKEND=regcomp_l -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=leaks -DUSE_GSSAPI=ON -DEXPERIMENTAL_SHA256=ON + PKG_CONFIG_PATH: /usr/local/opt/openssl/lib/pkgconfig + SKIP_SSH_TESTS: true + SKIP_NEGOTIATE_TESTS: true + setup-script: osx + - name: "Windows (SHA256, amd64, Visual Studio)" + id: windows-amd64-vs + os: windows-2019 + env: + ARCH: amd64 + CMAKE_GENERATOR: Visual Studio 16 2019 + CMAKE_OPTIONS: -A x64 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON -DEXPERIMENTAL_SHA256=ON + SKIP_SSH_TESTS: true + SKIP_NEGOTIATE_TESTS: true fail-fast: false - name: "Build ${{ matrix.platform.name }}" env: ${{ matrix.platform.env }} runs-on: ${{ matrix.platform.os }} + name: "Build ${{ matrix.platform.name }}" steps: - name: Check out repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: path: source fetch-depth: 0 @@ -333,7 +363,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: path: source fetch-depth: 0 @@ -358,13 +388,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v2 with: languages: 'cpp' @@ -376,4 +406,4 @@ jobs: cmake --build . - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + uses: github/codeql-action/analyze@v2 diff --git a/CMakeLists.txt b/CMakeLists.txt index e76fc129a..1f2e02367 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 3.5.1) -project(libgit2 VERSION "1.5.1" LANGUAGES C) +project(libgit2 VERSION "1.6.4" LANGUAGES C) # Add find modules to the path set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake") @@ -15,6 +15,9 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake") # Build options # +# Experimental features +option(EXPERIMENTAL_SHA256 "Enable experimental SHA256 support (for R&D/testing)" OFF) + # Optional subsystems option(BUILD_SHARED_LIBS "Build Shared Library (OFF for Static)" ON) option(BUILD_TESTS "Build Tests using the Clar suite" ON) @@ -107,6 +110,7 @@ include(IdeSplitSources) include(FeatureSummary) include(EnableWarnings) include(DefaultCFlags) +include(ExperimentalFeatures) # diff --git a/COPYING b/COPYING index 28226696d..25c8d8c6b 100644 --- a/COPYING +++ b/COPYING @@ -1184,3 +1184,33 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +---------------------------------------------------------------------- + +The built-in git_fs_path_basename_r() function is based on the +Android implementation, BSD licensed: + +Copyright (C) 2008 The Android Open Source Project +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/README.md b/README.md index a9deaa01d..93476f9c0 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,8 @@ libgit2 - the Git linkable library | Build Status | | | ------------ | - | | **main** branch CI builds | [![CI Build](https://github.com/libgit2/libgit2/workflows/CI%20Build/badge.svg?event=push)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22CI+Build%22+event%3Apush) | -| **v1.4 branch** CI builds | [![CI Build](https://github.com/libgit2/libgit2/workflows/CI%20Build/badge.svg?branch=maint%2Fv1.4&event=push)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22CI+Build%22+event%3Apush+branch%3Amaint%2Fv1.4) | -| **v1.3 branch** CI builds | [![CI Build](https://github.com/libgit2/libgit2/workflows/CI%20Build/badge.svg?branch=maint%2Fv1.3&event=push)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22CI+Build%22+event%3Apush+branch%3Amaint%2Fv1.3) | +| **v1.6 branch** CI builds | [![CI Build](https://github.com/libgit2/libgit2/workflows/CI%20Build/badge.svg?branch=maint%2Fv1.6&event=push)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22CI+Build%22+event%3Apush+branch%3Amaint%2Fv1.6) | +| **v1.5 branch** CI builds | [![CI Build](https://github.com/libgit2/libgit2/workflows/CI%20Build/badge.svg?branch=maint%2Fv1.5&event=push)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22CI+Build%22+event%3Apush+branch%3Amaint%2Fv1.5) | | **Nightly** builds | [![Nightly Build](https://github.com/libgit2/libgit2/workflows/Nightly%20Build/badge.svg)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22Nightly+Build%22) [![Coverity Scan Status](https://scan.coverity.com/projects/639/badge.svg)](https://scan.coverity.com/projects/639) | `libgit2` is a portable, pure C implementation of the Git core methods @@ -25,8 +25,9 @@ and on Git hosting providers like [GitHub](https://github.com/), We perform the merge every time you click "merge pull request". `libgit2` is licensed under a **very permissive license** (GPLv2 with a special -Linking Exception). This basically means that you can link it (unmodified) -with any kind of software without having to release its source code. +Linking Exception). This means that you can link against the library with any +kind of software without making that software fall under the GPL. +Changes to libgit2 would still be covered under its GPL license. Additionally, the example code has been released to the public domain (see the [separate license](examples/COPYING) for more information). @@ -395,7 +396,7 @@ Here are the bindings to libgit2 that are currently available: * Pharo Smalltalk * libgit2-pharo-bindings * PHP - * php-git + * php-git2 * Python * pygit2 * R diff --git a/ci/build.sh b/ci/build.sh index 21a45af5f..80e7a61ae 100755 --- a/ci/build.sh +++ b/ci/build.sh @@ -13,16 +13,30 @@ BUILD_PATH=${BUILD_PATH:=$PATH} CMAKE=$(which cmake) CMAKE_GENERATOR=${CMAKE_GENERATOR:-Unix Makefiles} +indent() { sed "s/^/ /"; } + +cygfullpath() { + result=$(echo "${1}" | tr \; \\n | while read -r element; do + if [ "${last}" != "" ]; then echo -n ":"; fi + echo -n $(cygpath "${element}") + last="${element}" + done) + if [ "${result}" = "" ]; then exit 1; fi + echo "${result}" +} + if [[ "$(uname -s)" == MINGW* ]]; then - BUILD_PATH=$(cygpath "$BUILD_PATH") + BUILD_PATH=$(cygfullpath "${BUILD_PATH}") fi -indent() { sed "s/^/ /"; } echo "Source directory: ${SOURCE_DIR}" echo "Build directory: ${BUILD_DIR}" echo "" +echo "Platform:" +uname -s | indent + if [ "$(uname -s)" = "Darwin" ]; then echo "macOS version:" sw_vers | indent @@ -40,7 +54,7 @@ echo "Kernel version:" uname -a 2>&1 | indent echo "CMake version:" -env PATH="${BUILD_PATH}" "${CMAKE}" --version 2>&1 | indent +env PATH="${BUILD_PATH}" "${CMAKE}" --version | head -1 2>&1 | indent if test -n "${CC}"; then echo "Compiler version:" diff --git a/ci/docker/xenial b/ci/docker/xenial index f5fa5a315..578f0a962 100644 --- a/ci/docker/xenial +++ b/ci/docker/xenial @@ -7,11 +7,13 @@ RUN apt-get update && \ clang \ cmake \ curl \ + gettext \ gcc \ - git \ krb5-user \ libcurl4-gnutls-dev \ + libexpat1-dev \ libgcrypt20-dev \ + libintl-perl \ libkrb5-dev \ libpcre3-dev \ libssl-dev \ @@ -28,7 +30,17 @@ RUN apt-get update && \ && \ rm -rf /var/lib/apt/lists/* -FROM apt AS mbedtls +FROM apt AS git +RUN cd /tmp && \ + curl --location --silent --show-error https://github.com/git/git/archive/refs/tags/v2.39.1.tar.gz | \ + tar -xz && \ + cd git-2.39.1 && \ + make && \ + make prefix=/usr install && \ + cd .. && \ + rm -rf git-2.39.1 + +FROM git AS mbedtls RUN cd /tmp && \ curl --location --silent --show-error https://github.com/Mbed-TLS/mbedtls/archive/refs/tags/mbedtls-2.16.2.tar.gz | \ tar -xz && \ diff --git a/ci/setup-mingw-build.sh b/ci/setup-mingw-build.sh index 3d72b24eb..6c444f584 100755 --- a/ci/setup-mingw-build.sh +++ b/ci/setup-mingw-build.sh @@ -11,9 +11,9 @@ BUILD_TEMP=$(cygpath $BUILD_TEMP) case "$ARCH" in amd64) - MINGW_URI="https://github.com/libgit2/ci-dependencies/releases/download/2021-05-04/mingw-x86_64-8.1.0-release-win32-sjlj-rt_v6-rev0.zip";; + MINGW_URI="https://github.com/libgit2/ci-dependencies/releases/download/2023-01-23/mingw-x86_64-8.1.0-release-win32-sjlj-rt_v6-rev0.zip";; x86) - MINGW_URI="https://github.com/libgit2/ci-dependencies/releases/download/2021-05-04/mingw-i686-8.1.0-release-win32-sjlj-rt_v6-rev0.zip";; + MINGW_URI="https://github.com/libgit2/ci-dependencies/releases/download/2023-01-23/mingw-i686-8.1.0-release-win32-sjlj-rt_v6-rev0.zip";; esac if [ -z "$MINGW_URI" ]; then diff --git a/ci/setup-win32-build.sh b/ci/setup-win32-build.sh new file mode 100755 index 000000000..a8b81e5ef --- /dev/null +++ b/ci/setup-win32-build.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +set -ex + +echo "##############################################################################" +echo "## Downloading libssh2" +echo "##############################################################################" + +BUILD_TEMP=${BUILD_TEMP:=$TEMP} +BUILD_TEMP=$(cygpath $BUILD_TEMP) + +case "$ARCH" in + amd64) + LIBSSH2_URI="https://github.com/libgit2/ci-dependencies/releases/download/2023-02-01/libssh2-20230201-amd64.zip";; + x86) + LIBSSH2_URI="https://github.com/libgit2/ci-dependencies/releases/download/2023-02-01-v2/libssh2-20230201-x86.zip";; +esac + +if [ -z "$LIBSSH2_URI" ]; then + echo "No URL" + exit 1 +fi + +mkdir -p "$BUILD_TEMP" + +curl -s -L "$LIBSSH2_URI" -o "$BUILD_TEMP"/libssh2-"$ARCH".zip +unzip -q "$BUILD_TEMP"/libssh2-"$ARCH".zip -d "$BUILD_TEMP" diff --git a/ci/test.sh b/ci/test.sh index 60d94caf8..c46cf0dc4 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -13,22 +13,52 @@ fi SOURCE_DIR=${SOURCE_DIR:-$( cd "$( dirname "${BASH_SOURCE[0]}" )" && dirname $( pwd ) )} BUILD_DIR=$(pwd) +BUILD_PATH=${BUILD_PATH:=$PATH} +CTEST=$(which ctest) TMPDIR=${TMPDIR:-/tmp} USER=${USER:-$(whoami)} +HOME=`mktemp -d ${TMPDIR}/home.XXXXXXXX` +export CLAR_HOMEDIR=${HOME} + SUCCESS=1 CONTINUE_ON_FAILURE=0 cleanup() { echo "Cleaning up..." - if [ ! -z "$GITDAEMON_PID" ]; then - echo "Stopping git daemon..." - kill $GITDAEMON_PID + if [ ! -z "$GIT_STANDARD_PID" ]; then + echo "Stopping git daemon (standard)..." + kill $GIT_STANDARD_PID + fi + + if [ ! -z "$GIT_NAMESPACE_PID" ]; then + echo "Stopping git daemon (namespace)..." + kill $GIT_NAMESPACE_PID + fi + + if [ ! -z "$GIT_SHA256_PID" ]; then + echo "Stopping git daemon (sha256)..." + kill $GIT_SHA256_PID + fi + + if [ ! -z "$PROXY_BASIC_PID" ]; then + echo "Stopping proxy (Basic)..." + kill $PROXY_BASIC_PID + fi + + if [ ! -z "$PROXY_NTLM_PID" ]; then + echo "Stopping proxy (NTLM)..." + kill $PROXY_NTLM_PID + fi + + if [ ! -z "$HTTP_PID" ]; then + echo "Stopping HTTP server..." + kill $HTTP_PID fi if [ ! -z "$SSHD_DIR" -a -f "${SSHD_DIR}/pid" ]; then - echo "Stopping SSH..." + echo "Stopping SSH server..." kill $(cat "${SSHD_DIR}/pid") fi @@ -52,7 +82,11 @@ run_test() { RETURN_CODE=0 - CLAR_SUMMARY="${BUILD_DIR}/results_${1}.xml" ctest -V -R "^${1}$" || RETURN_CODE=$? && true + ( + export PATH="${BUILD_PATH}" + export CLAR_SUMMARY="${BUILD_DIR}/results_${1}.xml" + "${CTEST}" -V -R "^${1}$" + ) || RETURN_CODE=$? && true if [ "$RETURN_CODE" -eq 0 ]; then FAILED=0 @@ -73,48 +107,81 @@ run_test() { fi } +indent() { sed "s/^/ /"; } + +cygfullpath() { + result=$(echo "${1}" | tr \; \\n | while read -r element; do + if [ "${last}" != "" ]; then echo -n ":"; fi + echo -n $(cygpath "${element}") + last="${element}" + done) + if [ "${result}" = "" ]; then exit 1; fi + echo "${result}" +} + +if [[ "$(uname -s)" == MINGW* ]]; then + BUILD_PATH=$(cygfullpath "$BUILD_PATH") +fi + + # Configure the test environment; run them early so that we're certain # that they're started by the time we need them. +echo "CTest version:" +env PATH="${BUILD_PATH}" "${CTEST}" --version | head -1 2>&1 | indent + +echo "" + echo "##############################################################################" echo "## Configuring test environment" echo "##############################################################################" +echo "" + if [ -z "$SKIP_GITDAEMON_TESTS" ]; then - echo "Starting git daemon..." - GITDAEMON_DIR=`mktemp -d ${TMPDIR}/gitdaemon.XXXXXXXX` - git init --bare "${GITDAEMON_DIR}/test.git" >/dev/null - git daemon --listen=localhost --export-all --enable=receive-pack --base-path="${GITDAEMON_DIR}" "${GITDAEMON_DIR}" 2>/dev/null & - GITDAEMON_PID=$! - disown $GITDAEMON_PID + echo "Starting git daemon (standard)..." + GIT_STANDARD_DIR=`mktemp -d ${TMPDIR}/git_standard.XXXXXXXX` + git init --bare "${GIT_STANDARD_DIR}/test.git" >/dev/null + git daemon --listen=localhost --export-all --enable=receive-pack --base-path="${GIT_STANDARD_DIR}" "${GIT_STANDARD_DIR}" 2>/dev/null & + GIT_STANDARD_PID=$! + + echo "Starting git daemon (namespace)..." + GIT_NAMESPACE_DIR=`mktemp -d ${TMPDIR}/git_namespace.XXXXXXXX` + cp -R "${SOURCE_DIR}/tests/resources/namespace.git" "${GIT_NAMESPACE_DIR}/namespace.git" + GIT_NAMESPACE="name1" git daemon --listen=localhost --port=9419 --export-all --enable=receive-pack --base-path="${GIT_NAMESPACE_DIR}" "${GIT_NAMESPACE_DIR}" & + GIT_NAMESPACE_PID=$! + + echo "Starting git daemon (sha256)..." + GIT_SHA256_DIR=`mktemp -d ${TMPDIR}/git_sha256.XXXXXXXX` + cp -R "${SOURCE_DIR}/tests/resources/testrepo_256.git" "${GIT_SHA256_DIR}/testrepo_256.git" + git daemon --listen=localhost --port=9420 --export-all --enable=receive-pack --base-path="${GIT_SHA256_DIR}" "${GIT_SHA256_DIR}" & + GIT_SHA256_PID=$! fi if [ -z "$SKIP_PROXY_TESTS" ]; then curl --location --silent --show-error https://github.com/ethomson/poxyproxy/releases/download/v0.7.0/poxyproxy-0.7.0.jar >poxyproxy.jar - echo "" echo "Starting HTTP proxy (Basic)..." java -jar poxyproxy.jar --address 127.0.0.1 --port 8080 --credentials foo:bar --auth-type basic --quiet & + PROXY_BASIC_PID=$! - echo "" echo "Starting HTTP proxy (NTLM)..." java -jar poxyproxy.jar --address 127.0.0.1 --port 8090 --credentials foo:bar --auth-type ntlm --quiet & + PROXY_NTLM_PID=$! fi if [ -z "$SKIP_NTLM_TESTS" -o -z "$SKIP_ONLINE_TESTS" ]; then curl --location --silent --show-error https://github.com/ethomson/poxygit/releases/download/v0.5.1/poxygit-0.5.1.jar >poxygit.jar - echo "" echo "Starting HTTP server..." - NTLM_DIR=`mktemp -d ${TMPDIR}/ntlm.XXXXXXXX` - git init --bare "${NTLM_DIR}/test.git" - java -jar poxygit.jar --address 127.0.0.1 --port 9000 --credentials foo:baz --quiet "${NTLM_DIR}" & + HTTP_DIR=`mktemp -d ${TMPDIR}/http.XXXXXXXX` + git init --bare "${HTTP_DIR}/test.git" + java -jar poxygit.jar --address 127.0.0.1 --port 9000 --credentials foo:baz --quiet "${HTTP_DIR}" & + HTTP_PID=$! fi if [ -z "$SKIP_SSH_TESTS" ]; then - echo "" - echo "Starting ssh daemon..." - HOME=`mktemp -d ${TMPDIR}/home.XXXXXXXX` + echo "Starting SSH server..." SSHD_DIR=`mktemp -d ${TMPDIR}/sshd.XXXXXXXX` git init --bare "${SSHD_DIR}/test.git" >/dev/null cat >"${SSHD_DIR}/sshd_config" <<-EOF @@ -219,12 +286,30 @@ fi if [ -z "$SKIP_GITDAEMON_TESTS" ]; then echo "" - echo "Running gitdaemon tests" + echo "Running gitdaemon (standard) tests" echo "" export GITTEST_REMOTE_URL="git://localhost/test.git" run_test gitdaemon unset GITTEST_REMOTE_URL + + echo "" + echo "Running gitdaemon (namespace) tests" + echo "" + + export GITTEST_REMOTE_URL="git://localhost:9419/namespace.git" + export GITTEST_REMOTE_BRANCH="four" + run_test gitdaemon_namespace + unset GITTEST_REMOTE_URL + unset GITTEST_REMOTE_BRANCH + + echo "" + echo "Running gitdaemon (sha256) tests" + echo "" + + export GITTEST_REMOTE_URL="git://localhost:9420/testrepo_256.git" + run_test gitdaemon_sha256 + unset GITTEST_REMOTE_URL fi if [ -z "$SKIP_PROXY_TESTS" ]; then @@ -348,7 +433,7 @@ if [ -z "$SKIP_FUZZERS" ]; then echo "## Running fuzzers" echo "##############################################################################" - ctest -V -R 'fuzzer' + env PATH="${BUILD_PATH}" "${CTEST}" -V -R 'fuzzer' fi cleanup diff --git a/cmake/ExperimentalFeatures.cmake b/cmake/ExperimentalFeatures.cmake new file mode 100644 index 000000000..7eff40bdb --- /dev/null +++ b/cmake/ExperimentalFeatures.cmake @@ -0,0 +1,23 @@ +# Experimental feature support for libgit2 - developers can opt in to +# experimental functionality, like sha256 support. When experimental +# functionality is enabled, we set both a cmake flag *and* a compile +# definition. The cmake flag is used to generate `experimental.h`, +# which will be installed by a `make install`. But the compile definition +# is used by the libgit2 sources to detect the functionality at library +# build time. This allows us to have an in-tree `experimental.h` with +# *no* experiments enabled. This lets us support users who build without +# cmake and cannot generate the `experimental.h` file. + +if(EXPERIMENTAL_SHA256) + add_feature_info("SHA256 API" ON "experimental SHA256 APIs") + + set(EXPERIMENTAL 1) + set(GIT_EXPERIMENTAL_SHA256 1) + add_definitions(-DGIT_EXPERIMENTAL_SHA256=1) +else() + add_feature_info("SHA256 API" OFF "experimental SHA256 APIs") +endif() + +if(EXPERIMENTAL) + set(LIBGIT2_FILENAME "${LIBGIT2_FILENAME}-experimental") +endif() diff --git a/docs/changelog.md b/docs/changelog.md index 448a8a0ff..d970b48e9 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,13 +1,154 @@ -v1.5.1 +v1.6.4 ------ -🔒 This is a security release to address CVE-2023-22742: when compiled using the optional, included libssh2 backend, libgit2 fails to verify SSH keys by default. +## What's Changed -When using an SSH remote with the optional, included libssh2 backend, libgit2 does not perform certificate checking by default. Prior versions of libgit2 require the caller to set the `certificate_check` field of libgit2's `git_remote_callbacks` structure - if a certificate check callback is not set, libgit2 does not perform any certificate checking. This means that by default - without configuring a certificate check callback, clients will not perform validation on the server SSH keys and may be subject to a man-in-the-middle attack. +### Bug fixes +* config: return `GIT_ENOTFOUND` for missing programdata by @ethomson in https://github.com/libgit2/libgit2/pull/6547 -The libgit2 security team would like to thank the Julia and Rust security teams for responsibly disclosing this vulnerability and assisting with fixing the vulnerability. +**Full Changelog**: https://github.com/libgit2/libgit2/compare/v1.6.3...v1.6.4 -All users of the v1.5 release line are recommended to upgrade. +v1.6.3 +------ + +## What's Changed + +### Bug fixes + +* odb: restore `git_odb_open` by @ethomson in https://github.com/libgit2/libgit2/pull/6520 +* Ensure that `git_index_add_all` handles ignored directories by @ethomson in https://github.com/libgit2/libgit2/pull/6521 +* pack: use 64 bits for the number of objects by @carlosmn in https://github.com/libgit2/libgit2/pull/6530 + +### Build and CI improvements + +* Remove unused wditer variable by @georgthegreat in https://github.com/libgit2/libgit2/pull/6518 +* fs_path: let root run the ownership tests by @ethomson in https://github.com/libgit2/libgit2/pull/6513 +* sysdir: Do not declare win32 functions on non-win32 platforms by @Batchyx in https://github.com/libgit2/libgit2/pull/6527 +* cmake: don't include `include/git2` by @ethomson in https://github.com/libgit2/libgit2/pull/6529 + +## New Contributors +* @georgthegreat made their first contribution in https://github.com/libgit2/libgit2/pull/6518 + +**Full Changelog**: https://github.com/libgit2/libgit2/compare/v1.6.2...v1.6.3 + +v1.6.2 +------ + +## What's Changed +### Bug fixes + +* remote: always populate old id in update tips by @ethomson in https://github.com/libgit2/libgit2/pull/6506 + The update tips callback would not always be properly provided with an empty (`0000000...`) OID for new refs. + +* Revert #6503 by @ethomson in https://github.com/libgit2/libgit2/pull/6511 + The certificate callback added port information for callbacks in #6503, but the format was ambiguous with IPv6 addresses. Revert this change temporarily. + +* Add `git_odb_backend_loose` back by @ethomson in https://github.com/libgit2/libgit2/pull/6512 + During SHA256 refactoring, the `git_odb_backend_loose` API was accidentally removed. Add it back. + +* meta: configure pkg-config .pc correctly by @ethomson in https://github.com/libgit2/libgit2/pull/6514 + During SHA256 refactoring, the pkg-config `.pc` file was erroneously renamed to `git2` instead of `libgit2`. Repair this. + +**Full Changelog**: https://github.com/libgit2/libgit2/compare/v1.6.1...v1.6.2 + +v1.6 +---- + +This is release v1.6.1, "Hubbeliges Krokodil". This release adds experimental SHA256 support and includes many new features and bugfixes. This release replaces libgit2 v1.6.0, which did not correctly update its version number(s). + +## What's Changed + +### New features + +* **Support for bare repositories with SHA256 support (experimental)** by @ethomson in https://github.com/libgit2/libgit2/pull/6191 + You can configure experimental SHA256 support in libgit2 with `cmake -DEXPERIMENTAL_SHA256=ON` during project setup. This is useful for considering future integrations, work on clients, and work on language bindings. At present, working with bare repositories should largely work, including remote operations. But many pieces of functionality - including working with the index - are not yet supported. As a result, **libgit2 with SHA256 support should not be used in production or released with package distribution.** + +* **Support the notion of a home directory separately from global configuration directory** by @ethomson in https://github.com/libgit2/libgit2/pull/6455 and https://github.com/libgit2/libgit2/pull/6456 + Callers and language bindings can now configure the home directory that libgit2 uses for file lookups (eg, the `.ssh` directory). This configuration is separate from the git global configuration path. + +* **stash: partial stash specific files** by @gitkraken-jacobw in https://github.com/libgit2/libgit2/pull/6330 + A stash can be created with only specific files, using a pathspec. This is similar to the `git stash push` command. + +* **push: revparse refspec source, so you can push things that are not refs** by @sven-of-cord in https://github.com/libgit2/libgit2/pull/6362 + Pushes can be performed using refspecs instead of only references. + +* **Support OpenSSL3** by @ethomson in https://github.com/libgit2/libgit2/pull/6464 and https://github.com/libgit2/libgit2/pull/6471 + OpenSSL 3 is now supported, both when compiled directly and dynamically loaded. + +### Bug fixes +* winhttp: support long custom headers by @kcsaul in https://github.com/libgit2/libgit2/pull/6363 +* Fix memory leak by @csware in https://github.com/libgit2/libgit2/pull/6382 +* Don't fail the whole clone if you can't find a default branch by @torvalds in https://github.com/libgit2/libgit2/pull/6369 +* #6366: When a worktree is missing, return `GIT_ENOTFOUND`. by @arroz in https://github.com/libgit2/libgit2/pull/6395 +* commit-graph: only verify csum on `git_commit_graph_open()`. by @derrickstolee in https://github.com/libgit2/libgit2/pull/6420 +* Ignore missing 'safe.directory' config during ownership checks by @kcsaul in https://github.com/libgit2/libgit2/pull/6408 +* Fix leak in `git_tag_create_from_buffer` by @julianmesa-gitkraken in https://github.com/libgit2/libgit2/pull/6421 +* http: Update httpclient options when reusing an existing connection. by @slackner in https://github.com/libgit2/libgit2/pull/6416 +* Add support for `safe.directory *` by @csware in https://github.com/libgit2/libgit2/pull/6429 +* URL parsing for google-compatible URLs by @ethomson in https://github.com/libgit2/libgit2/pull/6326 +* Fixes #6433: `git_submodule_update` fails to update configured but missing submodule by @tagesuhu in https://github.com/libgit2/libgit2/pull/6434 +* transport: fix capabilities calculation by @russell in https://github.com/libgit2/libgit2/pull/6435 +* push: use resolved oid as the source by @ethomson in https://github.com/libgit2/libgit2/pull/6452 +* Use `git_clone__submodule` to avoid file checks in workdir by @abizjak in https://github.com/libgit2/libgit2/pull/6444 +* #6422: handle dangling symbolic refs gracefully by @arroz in https://github.com/libgit2/libgit2/pull/6423 +* `diff_file`: Fix crash when freeing a patch representing an empty untracked file by @jorio in https://github.com/libgit2/libgit2/pull/6475 +* clone: clean up options on failure by @ethomson in https://github.com/libgit2/libgit2/pull/6479 +* stash: update strarray usage by @ethomson in https://github.com/libgit2/libgit2/pull/6487 +* #6491: Sets `oid_type` on repos open with `git_repository_open_bare` by @arroz in https://github.com/libgit2/libgit2/pull/6492 +* Handle Win32 shares by @ethomson in https://github.com/libgit2/libgit2/pull/6493 +* Make failure to connect to ssh-agent non-fatal by @fxcoudert in https://github.com/libgit2/libgit2/pull/6497 +* odb: don't unconditionally add `oid_type` to stream by @ethomson in https://github.com/libgit2/libgit2/pull/6499 +* Pass hostkey & port to host verify callback by @fxcoudert in https://github.com/libgit2/libgit2/pull/6503 + +### Code cleanups +* meta: update version number to v1.6.0-alpha by @ethomson in https://github.com/libgit2/libgit2/pull/6352 +* sha256: indirection for experimental functions by @ethomson in https://github.com/libgit2/libgit2/pull/6354 +* Delete `create.c.bak` by @lrm29 in https://github.com/libgit2/libgit2/pull/6398 +* Support non-cmake builds with an in-tree `experimental.h` by @ethomson in https://github.com/libgit2/libgit2/pull/6405 + +### Build and CI improvements +* tests: skip flaky-ass googlesource tests by @ethomson in https://github.com/libgit2/libgit2/pull/6353 +* clar: remove ftrunacte from libgit2 tests by @boretrk in https://github.com/libgit2/libgit2/pull/6357 +* CI Improvements by @ethomson in https://github.com/libgit2/libgit2/pull/6403 +* fix compile on Windows with `-DWIN32_LEAN_AND_MEAN` by @christoph-cullmann in https://github.com/libgit2/libgit2/pull/6373 +* Fixes #6365 : Uppercase windows.h include fails build in case-sensitive OS by @Vinz2008 in https://github.com/libgit2/libgit2/pull/6377 +* ci: update version numbers of actions by @ethomson in https://github.com/libgit2/libgit2/pull/6448 +* thread: avoid warnings when building without threads by @ethomson in https://github.com/libgit2/libgit2/pull/6432 +* src: hide unused hmac() prototype by @0-wiz-0 in https://github.com/libgit2/libgit2/pull/6458 +* tests: update clar test runner by @ethomson in https://github.com/libgit2/libgit2/pull/6459 +* ci: always create test summaries, even on failure by @ethomson in https://github.com/libgit2/libgit2/pull/6460 +* Fix build failure with `-DEMBED_SSH_PATH` by @vicr123 in https://github.com/libgit2/libgit2/pull/6374 +* Define correct `off64_t` for AIX by @bzEq in https://github.com/libgit2/libgit2/pull/6376 +* Fix some warnings in main by @ethomson in https://github.com/libgit2/libgit2/pull/6480 +* strarray: remove deprecated declaration by @ethomson in https://github.com/libgit2/libgit2/pull/6486 +* tests: always unset `HTTP_PROXY` before starting tests by @ethomson in https://github.com/libgit2/libgit2/pull/6498 + +### Documentation improvements +* add 2-clause BSD license to COPYING by @martinvonz in https://github.com/libgit2/libgit2/pull/6413 +* Add new PHP bindings project to language bindings section of README.md by @RogerGee in https://github.com/libgit2/libgit2/pull/6473 +* README: clarify the linking exception by @ethomson in https://github.com/libgit2/libgit2/pull/6494 +* Correct the definition of "empty" in the docs for `git_repository_is_empty` by @timrogers in https://github.com/libgit2/libgit2/pull/6500 + +## New Contributors +* @christoph-cullmann made their first contribution in https://github.com/libgit2/libgit2/pull/6373 +* @Vinz2008 made their first contribution in https://github.com/libgit2/libgit2/pull/6377 +* @torvalds made their first contribution in https://github.com/libgit2/libgit2/pull/6369 +* @derrickstolee made their first contribution in https://github.com/libgit2/libgit2/pull/6420 +* @julianmesa-gitkraken made their first contribution in https://github.com/libgit2/libgit2/pull/6421 +* @slackner made their first contribution in https://github.com/libgit2/libgit2/pull/6416 +* @martinvonz made their first contribution in https://github.com/libgit2/libgit2/pull/6413 +* @tagesuhu made their first contribution in https://github.com/libgit2/libgit2/pull/6434 +* @russell made their first contribution in https://github.com/libgit2/libgit2/pull/6435 +* @sven-of-cord made their first contribution in https://github.com/libgit2/libgit2/pull/6362 +* @0-wiz-0 made their first contribution in https://github.com/libgit2/libgit2/pull/6458 +* @abizjak made their first contribution in https://github.com/libgit2/libgit2/pull/6444 +* @vicr123 made their first contribution in https://github.com/libgit2/libgit2/pull/6374 +* @bzEq made their first contribution in https://github.com/libgit2/libgit2/pull/6376 +* @gitkraken-jacobw made their first contribution in https://github.com/libgit2/libgit2/pull/6330 +* @fxcoudert made their first contribution in https://github.com/libgit2/libgit2/pull/6497 +* @timrogers made their first contribution in https://github.com/libgit2/libgit2/pull/6500 + +**Full Changelog**: https://github.com/libgit2/libgit2/compare/v1.5.0...v1.6.0 v1.5 ---- diff --git a/examples/cat-file.c b/examples/cat-file.c index b81e9a8da..741edb484 100644 --- a/examples/cat-file.c +++ b/examples/cat-file.c @@ -49,7 +49,7 @@ static void show_blob(const git_blob *blob) static void show_tree(const git_tree *tree) { size_t i, max_i = (int)git_tree_entrycount(tree); - char oidstr[GIT_OID_HEXSZ + 1]; + char oidstr[GIT_OID_SHA1_HEXSIZE + 1]; const git_tree_entry *te; for (i = 0; i < max_i; ++i) { @@ -70,7 +70,7 @@ static void show_tree(const git_tree *tree) static void show_commit(const git_commit *commit) { unsigned int i, max_i; - char oidstr[GIT_OID_HEXSZ + 1]; + char oidstr[GIT_OID_SHA1_HEXSIZE + 1]; git_oid_tostr(oidstr, sizeof(oidstr), git_commit_tree_id(commit)); printf("tree %s\n", oidstr); @@ -90,7 +90,7 @@ static void show_commit(const git_commit *commit) static void show_tag(const git_tag *tag) { - char oidstr[GIT_OID_HEXSZ + 1]; + char oidstr[GIT_OID_SHA1_HEXSIZE + 1]; git_oid_tostr(oidstr, sizeof(oidstr), git_tag_target_id(tag));; printf("object %s\n", oidstr); @@ -125,7 +125,7 @@ int lg2_cat_file(git_repository *repo, int argc, char *argv[]) { struct catfile_options o = { ".", NULL, 0, 0 }; git_object *obj = NULL; - char oidstr[GIT_OID_HEXSZ + 1]; + char oidstr[GIT_OID_SHA1_HEXSIZE + 1]; parse_opts(&o, argc, argv); @@ -133,7 +133,7 @@ int lg2_cat_file(git_repository *repo, int argc, char *argv[]) "Could not resolve", o.rev); if (o.verbose) { - char oidstr[GIT_OID_HEXSZ + 1]; + char oidstr[GIT_OID_SHA1_HEXSIZE + 1]; git_oid_tostr(oidstr, sizeof(oidstr), git_object_id(obj)); printf("%s %s\n--\n", diff --git a/examples/fetch.c b/examples/fetch.c index 2b5ed1112..bbd882cfb 100644 --- a/examples/fetch.c +++ b/examples/fetch.c @@ -15,17 +15,17 @@ static int progress_cb(const char *str, int len, void *data) */ static int update_cb(const char *refname, const git_oid *a, const git_oid *b, void *data) { - char a_str[GIT_OID_HEXSZ+1], b_str[GIT_OID_HEXSZ+1]; + char a_str[GIT_OID_SHA1_HEXSIZE+1], b_str[GIT_OID_SHA1_HEXSIZE+1]; (void)data; git_oid_fmt(b_str, b); - b_str[GIT_OID_HEXSZ] = '\0'; + b_str[GIT_OID_SHA1_HEXSIZE] = '\0'; if (git_oid_is_zero(a)) { printf("[new] %.20s %s\n", b_str, refname); } else { git_oid_fmt(a_str, a); - a_str[GIT_OID_HEXSZ] = '\0'; + a_str[GIT_OID_SHA1_HEXSIZE] = '\0'; printf("[updated] %.10s..%.10s %s\n", a_str, b_str, refname); } diff --git a/examples/for-each-ref.c b/examples/for-each-ref.c index 020dab474..a0706741a 100644 --- a/examples/for-each-ref.c +++ b/examples/for-each-ref.c @@ -5,7 +5,7 @@ static int show_ref(git_reference *ref, void *data) { git_repository *repo = data; git_reference *resolved = NULL; - char hex[GIT_OID_HEXSZ+1]; + char hex[GIT_OID_SHA1_HEXSIZE+1]; const git_oid *oid; git_object *obj; @@ -16,7 +16,7 @@ static int show_ref(git_reference *ref, void *data) oid = git_reference_target(resolved ? resolved : ref); git_oid_fmt(hex, oid); - hex[GIT_OID_HEXSZ] = 0; + hex[GIT_OID_SHA1_HEXSIZE] = 0; check_lg2(git_object_lookup(&obj, repo, oid, GIT_OBJECT_ANY), "Unable to lookup object", hex); diff --git a/examples/general.c b/examples/general.c index 2127ec0e1..7f44cd786 100644 --- a/examples/general.c +++ b/examples/general.c @@ -129,7 +129,7 @@ int lg2_general(git_repository *repo, int argc, char** argv) */ static void oid_parsing(git_oid *oid) { - char out[GIT_OID_HEXSZ+1]; + char out[GIT_OID_SHA1_HEXSIZE+1]; char hex[] = "4a202b346bb0fb0db7eff3cffeb3c70babbd2045"; printf("*Hex to Raw*\n"); @@ -142,7 +142,11 @@ static void oid_parsing(git_oid *oid) * this throughout the example for storing the value of the current SHA * key we're working with. */ +#ifdef GIT_EXPERIMENTAL_SHA256 + git_oid_fromstr(oid, hex, GIT_OID_SHA1); +#else git_oid_fromstr(oid, hex); +#endif /* * Once we've converted the string into the oid value, we can get the raw @@ -152,7 +156,7 @@ static void oid_parsing(git_oid *oid) * char hex value. */ printf("\n*Raw to Hex*\n"); - out[GIT_OID_HEXSZ] = '\0'; + out[GIT_OID_SHA1_HEXSIZE] = '\0'; /** * If you have a oid, you can easily get the hex value of the SHA as well. @@ -173,7 +177,7 @@ static void oid_parsing(git_oid *oid) */ static void object_database(git_repository *repo, git_oid *oid) { - char oid_hex[GIT_OID_HEXSZ+1] = { 0 }; + char oid_hex[GIT_OID_SHA1_HEXSIZE+1] = { 0 }; const unsigned char *data; const char *str_type; int error; @@ -266,7 +270,7 @@ static void commit_writing(git_repository *repo) git_tree *tree; git_commit *parent; git_signature *author, *committer; - char oid_hex[GIT_OID_HEXSZ+1] = { 0 }; + char oid_hex[GIT_OID_SHA1_HEXSIZE+1] = { 0 }; printf("\n*Commit Writing*\n"); @@ -287,9 +291,14 @@ static void commit_writing(git_repository *repo) * parents. Here we're creating oid objects to create the commit with, * but you can also use */ +#ifdef GIT_EXPERIMENTAL_SHA256 + git_oid_fromstr(&tree_id, "f60079018b664e4e79329a7ef9559c8d9e0378d1", GIT_OID_SHA1); + git_oid_fromstr(&parent_id, "5b5b025afb0b4c913b4c338a42934a3863bf3644", GIT_OID_SHA1); +#else git_oid_fromstr(&tree_id, "f60079018b664e4e79329a7ef9559c8d9e0378d1"); - git_tree_lookup(&tree, repo, &tree_id); git_oid_fromstr(&parent_id, "5b5b025afb0b4c913b4c338a42934a3863bf3644"); +#endif + git_tree_lookup(&tree, repo, &tree_id); git_commit_lookup(&parent, repo, &parent_id); /** @@ -345,7 +354,7 @@ static void commit_parsing(git_repository *repo) const git_signature *author, *cmtter; git_commit *commit, *parent; git_oid oid; - char oid_hex[GIT_OID_HEXSZ+1]; + char oid_hex[GIT_OID_SHA1_HEXSIZE+1]; const char *message; unsigned int parents, p; int error; @@ -353,7 +362,11 @@ static void commit_parsing(git_repository *repo) printf("\n*Commit Parsing*\n"); +#ifdef GIT_EXPERIMENTAL_SHA256 + git_oid_fromstr(&oid, "8496071c1b46c854b31185ea97743be6a8774479", GIT_OID_SHA1); +#else git_oid_fromstr(&oid, "8496071c1b46c854b31185ea97743be6a8774479"); +#endif error = git_commit_lookup(&commit, repo, &oid); check_error(error, "looking up commit"); @@ -422,7 +435,11 @@ static void tag_parsing(git_repository *repo) * We create an oid for the tag object if we know the SHA and look it up * the same way that we would a commit (or any other object). */ +#ifdef GIT_EXPERIMENTAL_SHA256 + git_oid_fromstr(&oid, "b25fa35b38051e4ae45d4222e795f9df2e43f1d1", GIT_OID_SHA1); +#else git_oid_fromstr(&oid, "b25fa35b38051e4ae45d4222e795f9df2e43f1d1"); +#endif error = git_tag_lookup(&tag, repo, &oid); check_error(error, "looking up tag"); @@ -470,7 +487,11 @@ static void tree_parsing(git_repository *repo) /** * Create the oid and lookup the tree object just like the other objects. */ +#ifdef GIT_EXPERIMENTAL_SHA256 + git_oid_fromstr(&oid, "f60079018b664e4e79329a7ef9559c8d9e0378d1", GIT_OID_SHA1); +#else git_oid_fromstr(&oid, "f60079018b664e4e79329a7ef9559c8d9e0378d1"); +#endif git_tree_lookup(&tree, repo, &oid); /** @@ -524,7 +545,11 @@ static void blob_parsing(git_repository *repo) printf("\n*Blob Parsing*\n"); +#ifdef GIT_EXPERIMENTAL_SHA256 + git_oid_fromstr(&oid, "1385f264afb75a56a5bec74243be9b367ba4ca08", GIT_OID_SHA1); +#else git_oid_fromstr(&oid, "1385f264afb75a56a5bec74243be9b367ba4ca08"); +#endif git_blob_lookup(&blob, repo, &oid); /** @@ -566,7 +591,11 @@ static void revwalking(git_repository *repo) printf("\n*Revwalking*\n"); +#ifdef GIT_EXPERIMENTAL_SHA256 + git_oid_fromstr(&oid, "5b5b025afb0b4c913b4c338a42934a3863bf3644", GIT_OID_SHA1); +#else git_oid_fromstr(&oid, "5b5b025afb0b4c913b4c338a42934a3863bf3644"); +#endif /** * To use the revwalker, create a new walker, tell it how you want to sort @@ -679,7 +708,7 @@ static void reference_listing(git_repository *repo) for (i = 0; i < ref_list.count; ++i) { git_reference *ref; - char oid_hex[GIT_OID_HEXSZ+1] = GIT_OID_HEX_ZERO; + char oid_hex[GIT_OID_SHA1_HEXSIZE+1] = GIT_OID_SHA1_HEXZERO; const char *refname; refname = ref_list.strings[i]; diff --git a/examples/index-pack.c b/examples/index-pack.c index df37dd0c4..0f8234c75 100644 --- a/examples/index-pack.c +++ b/examples/index-pack.c @@ -28,11 +28,18 @@ int lg2_index_pack(git_repository *repo, int argc, char **argv) return EXIT_FAILURE; } - if (git_indexer_new(&idx, ".", 0, NULL, NULL) < 0) { +#ifdef GIT_EXPERIMENTAL_SHA256 + error = git_indexer_new(&idx, ".", git_repository_oid_type(repo), NULL); +#else + error = git_indexer_new(&idx, ".", 0, NULL, NULL); +#endif + + if (error < 0) { puts("bad idx"); return -1; } + if ((fd = open(argv[1], 0)) < 0) { perror("open"); return -1; diff --git a/examples/log.c b/examples/log.c index 9060f3f3e..4b0a95dcd 100644 --- a/examples/log.c +++ b/examples/log.c @@ -329,7 +329,7 @@ static void print_time(const git_time *intime, const char *prefix) /** Helper to print a commit object. */ static void print_commit(git_commit *commit, struct log_options *opts) { - char buf[GIT_OID_HEXSZ + 1]; + char buf[GIT_OID_SHA1_HEXSIZE + 1]; int i, count; const git_signature *sig; const char *scan, *eol; diff --git a/examples/ls-remote.c b/examples/ls-remote.c index 03ed887d1..24caae712 100644 --- a/examples/ls-remote.c +++ b/examples/ls-remote.c @@ -34,7 +34,7 @@ static int use_remote(git_repository *repo, char *name) goto cleanup; for (i = 0; i < refs_len; i++) { - char oid[GIT_OID_HEXSZ + 1] = {0}; + char oid[GIT_OID_SHA1_HEXSIZE + 1] = {0}; git_oid_fmt(oid, &refs[i]->oid); printf("%s\t%s\n", oid, refs[i]->name); } diff --git a/examples/rev-list.c b/examples/rev-list.c index d10f16690..cf8ac30c6 100644 --- a/examples/rev-list.c +++ b/examples/rev-list.c @@ -26,7 +26,7 @@ int lg2_rev_list(git_repository *repo, int argc, char **argv) git_revwalk *walk; git_oid oid; git_sort_t sort; - char buf[GIT_OID_HEXSZ+1]; + char buf[GIT_OID_SHA1_HEXSIZE+1]; check_lg2(revwalk_parse_options(&sort, &args), "parsing options", NULL); @@ -36,7 +36,7 @@ int lg2_rev_list(git_repository *repo, int argc, char **argv) while (!git_revwalk_next(&oid, walk)) { git_oid_fmt(buf, &oid); - buf[GIT_OID_HEXSZ] = '\0'; + buf[GIT_OID_SHA1_HEXSIZE] = '\0'; printf("%s\n", buf); } @@ -140,8 +140,14 @@ static int revwalk_parse_revs(git_repository *repo, git_revwalk *walk, struct ar if (push_spec(repo, walk, curr, hide) == 0) continue; +#ifdef GIT_EXPERIMENTAL_SHA256 + if ((error = git_oid_fromstr(&oid, curr, GIT_OID_SHA1))) + return error; +#else if ((error = git_oid_fromstr(&oid, curr))) return error; +#endif + if ((error = push_commit(walk, &oid, hide))) return error; } diff --git a/examples/rev-parse.c b/examples/rev-parse.c index 90258c101..3f68d79b7 100644 --- a/examples/rev-parse.c +++ b/examples/rev-parse.c @@ -65,7 +65,7 @@ static void parse_opts(struct parse_state *ps, int argc, char *argv[]) static int parse_revision(git_repository *repo, struct parse_state *ps) { git_revspec rs; - char str[GIT_OID_HEXSZ + 1]; + char str[GIT_OID_SHA1_HEXSIZE + 1]; check_lg2(git_revparse(&rs, repo, ps->spec), "Could not parse", ps->spec); diff --git a/examples/show-index.c b/examples/show-index.c index 7aaa45e65..fb797e04b 100644 --- a/examples/show-index.c +++ b/examples/show-index.c @@ -20,8 +20,8 @@ int lg2_show_index(git_repository *repo, int argc, char **argv) size_t i, ecount; char *dir = "."; size_t dirlen; - char out[GIT_OID_HEXSZ+1]; - out[GIT_OID_HEXSZ] = '\0'; + char out[GIT_OID_SHA1_HEXSIZE+1]; + out[GIT_OID_SHA1_HEXSIZE] = '\0'; if (argc > 2) fatal("usage: showindex []", NULL); diff --git a/fuzzers/commit_graph_fuzzer.c b/fuzzers/commit_graph_fuzzer.c index 1c46d78c7..9c1443e52 100644 --- a/fuzzers/commit_graph_fuzzer.c +++ b/fuzzers/commit_graph_fuzzer.c @@ -37,7 +37,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) git_commit_graph_entry e; git_str commit_graph_buf = GIT_STR_INIT; unsigned char hash[GIT_HASH_SHA1_SIZE]; - git_oid oid = {{0}}; + git_oid oid = GIT_OID_NONE; bool append_hash = false; if (size < 4) @@ -62,7 +62,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) memcpy(commit_graph_buf.ptr, data, size); memcpy(commit_graph_buf.ptr + size, hash, GIT_HASH_SHA1_SIZE); - memcpy(oid.id, hash, GIT_OID_RAWSZ); + memcpy(oid.id, hash, GIT_OID_SHA1_SIZE); } else { git_str_attach_notowned(&commit_graph_buf, (char *)data, size); } @@ -75,7 +75,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) goto cleanup; /* Search for any oid, just to exercise that codepath. */ - if (git_commit_graph_entry_find(&e, &file, &oid, GIT_OID_HEXSZ) < 0) + if (git_commit_graph_entry_find(&e, &file, &oid, GIT_OID_SHA1_HEXSIZE) < 0) goto cleanup; cleanup: diff --git a/fuzzers/midx_fuzzer.c b/fuzzers/midx_fuzzer.c index 4c3124e47..21fb90361 100644 --- a/fuzzers/midx_fuzzer.c +++ b/fuzzers/midx_fuzzer.c @@ -36,7 +36,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) git_midx_entry e; git_str midx_buf = GIT_STR_INIT; unsigned char hash[GIT_HASH_SHA1_SIZE]; - git_oid oid = {{0}}; + git_oid oid = GIT_OID_NONE; bool append_hash = false; if (size < 4) @@ -61,7 +61,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) memcpy(midx_buf.ptr, data, size); memcpy(midx_buf.ptr + size, hash, GIT_HASH_SHA1_SIZE); - memcpy(oid.id, hash, GIT_OID_RAWSZ); + memcpy(oid.id, hash, GIT_OID_SHA1_SIZE); } else { git_str_attach_notowned(&midx_buf, (char *)data, size); } @@ -70,7 +70,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) goto cleanup; /* Search for any oid, just to exercise that codepath. */ - if (git_midx_entry_find(&e, &idx, &oid, GIT_OID_HEXSZ) < 0) + if (git_midx_entry_find(&e, &idx, &oid, GIT_OID_SHA1_HEXSIZE) < 0) goto cleanup; cleanup: diff --git a/fuzzers/objects_fuzzer.c b/fuzzers/objects_fuzzer.c index 51b4a1ed4..7294e9b35 100644 --- a/fuzzers/objects_fuzzer.c +++ b/fuzzers/objects_fuzzer.c @@ -39,7 +39,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) * to do. */ for (i = 0; i < ARRAY_SIZE(types); i++) { - if (git_object__from_raw(&object, (const char *) data, size, types[i]) < 0) + if (git_object__from_raw(&object, (const char *) data, size, types[i], GIT_OID_SHA1) < 0) continue; git_object_free(object); object = NULL; diff --git a/fuzzers/packfile_fuzzer.c b/fuzzers/packfile_fuzzer.c index 23ecaf80f..aeba9575c 100644 --- a/fuzzers/packfile_fuzzer.c +++ b/fuzzers/packfile_fuzzer.c @@ -36,10 +36,19 @@ int LLVMFuzzerInitialize(int *argc, char ***argv) fprintf(stderr, "Failed to limit maximum pack object count\n"); abort(); } + +#ifdef GIT_EXPERIMENTAL_SHA256 + if (git_odb_new(&odb, NULL) < 0) { + fprintf(stderr, "Failed to create the odb\n"); + abort(); + } +#else if (git_odb_new(&odb) < 0) { fprintf(stderr, "Failed to create the odb\n"); abort(); } +#endif + if (git_mempack_new(&mempack) < 0) { fprintf(stderr, "Failed to create the mempack\n"); abort(); @@ -58,6 +67,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) git_str path = GIT_STR_INIT; git_oid oid; bool append_hash = false; + int error; if (size == 0) return 0; @@ -73,7 +83,13 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) abort(); } - if (git_indexer_new(&indexer, ".", 0, odb, NULL) < 0) { +#ifdef GIT_EXPERIMENTAL_SHA256 + error = git_indexer_new(&indexer, ".", GIT_OID_SHA1, NULL); +#else + error = git_indexer_new(&indexer, ".", 0, odb, NULL); +#endif + + if (error < 0) { fprintf(stderr, "Failed to create the indexer: %s\n", git_error_last()->message); abort(); @@ -90,11 +106,19 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) if (git_indexer_append(indexer, data, size, &stats) < 0) goto cleanup; if (append_hash) { +#ifdef GIT_EXPERIMENTAL_SHA256 + if (git_odb_hash(&oid, data, size, GIT_OBJECT_BLOB, GIT_OID_SHA1) < 0) { + fprintf(stderr, "Failed to compute the SHA1 hash\n"); + abort(); + } +#else if (git_odb_hash(&oid, data, size, GIT_OBJECT_BLOB) < 0) { fprintf(stderr, "Failed to compute the SHA1 hash\n"); abort(); } - if (git_indexer_append(indexer, &oid.id, GIT_OID_RAWSZ, &stats) < 0) { +#endif + + if (git_indexer_append(indexer, &oid.id, GIT_OID_SHA1_SIZE, &stats) < 0) { goto cleanup; } } diff --git a/include/git2.h b/include/git2.h index 2961cc3e5..3457e5f04 100644 --- a/include/git2.h +++ b/include/git2.h @@ -28,6 +28,7 @@ #include "git2/diff.h" #include "git2/email.h" #include "git2/errors.h" +#include "git2/experimental.h" #include "git2/filter.h" #include "git2/global.h" #include "git2/graph.h" diff --git a/include/git2/common.h b/include/git2/common.h index c3e3e7b4e..f968deb23 100644 --- a/include/git2/common.h +++ b/include/git2/common.h @@ -105,11 +105,6 @@ GIT_BEGIN_DECL */ #define GIT_PATH_MAX 4096 -/** - * The string representation of the null object ID. - */ -#define GIT_OID_HEX_ZERO "0000000000000000000000000000000000000000" - /** * Return the version of the libgit2 library * being currently used. @@ -227,7 +222,9 @@ typedef enum { GIT_OPT_GET_EXTENSIONS, GIT_OPT_SET_EXTENSIONS, GIT_OPT_GET_OWNER_VALIDATION, - GIT_OPT_SET_OWNER_VALIDATION + GIT_OPT_SET_OWNER_VALIDATION, + GIT_OPT_GET_HOMEDIR, + GIT_OPT_SET_HOMEDIR } git_libgit2_opt_t; /** @@ -473,6 +470,16 @@ typedef enum { * > Set that repository directories should be owned by the current * > user. The default is to validate ownership. * + * opts(GIT_OPT_GET_HOMEDIR, git_buf *out) + * > Gets the current user's home directory, as it will be used + * > for file lookups. The path is written to the `out` buffer. + * + * opts(GIT_OPT_SET_HOMEDIR, const char *path) + * > Sets the directory used as the current user's home directory, + * > for file lookups. + * > + * > - `path` directory of home directory. + * * @param option Option key * @param ... value to set the option * @return 0 on success, <0 on failure diff --git a/include/git2/deprecated.h b/include/git2/deprecated.h index c32abeeb7..52864ebe1 100644 --- a/include/git2/deprecated.h +++ b/include/git2/deprecated.h @@ -777,6 +777,12 @@ typedef git_trace_cb git_trace_callback; */ /**@{*/ +#ifndef GIT_EXPERIMENTAL_SHA256 +# define GIT_OID_RAWSZ GIT_OID_SHA1_SIZE +# define GIT_OID_HEXSZ GIT_OID_SHA1_HEXSIZE +# define GIT_OID_HEX_ZERO GIT_OID_SHA1_HEXZERO +#endif + GIT_EXTERN(int) git_oid_iszero(const git_oid *id); /**@}*/ diff --git a/include/git2/diff.h b/include/git2/diff.h index 3839f0033..850d215a6 100644 --- a/include/git2/diff.h +++ b/include/git2/diff.h @@ -274,7 +274,7 @@ typedef struct { /** * Represents the known length of the `id` field, when - * converted to a hex string. It is generally `GIT_OID_HEXSZ`, unless this + * converted to a hex string. It is generally `GIT_OID_SHA1_HEXSIZE`, unless this * delta was created from reading a patch file, in which case it may be * abbreviated to something reasonable, like 7 characters. */ diff --git a/include/git2/experimental.h b/include/git2/experimental.h new file mode 100644 index 000000000..06435f9a7 --- /dev/null +++ b/include/git2/experimental.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ + +#ifndef INCLUDE_experimental_h__ +#define INCLUDE_experimental_h__ + +/* + * This file exists to support users who build libgit2 with a bespoke + * build system and do not use our cmake configuration. Normally, cmake + * will create `experimental.h` from the `experimental.h.in` file and + * will include the generated file instead of this one. For non-cmake + * users, we bundle this `experimental.h` file which will be used + * instead. + */ + +#endif diff --git a/include/git2/indexer.h b/include/git2/indexer.h index ffe9bf366..630eef934 100644 --- a/include/git2/indexer.h +++ b/include/git2/indexer.h @@ -62,6 +62,19 @@ typedef int GIT_CALLBACK(git_indexer_progress_cb)(const git_indexer_progress *st typedef struct git_indexer_options { unsigned int version; +#ifdef GIT_EXPERIMENTAL_SHA256 + /** permissions to use creating packfile or 0 for defaults */ + unsigned int mode; + + /** + * object database from which to read base objects when + * fixing thin packs. This can be NULL if there are no thin + * packs; if a thin pack is encountered, an error will be + * returned if there are bases missing. + */ + git_odb *odb; +#endif + /** progress_cb function to call with progress information */ git_indexer_progress_cb progress_cb; @@ -87,6 +100,21 @@ GIT_EXTERN(int) git_indexer_options_init( git_indexer_options *opts, unsigned int version); +#ifdef GIT_EXPERIMENTAL_SHA256 +/** + * Create a new indexer instance + * + * @param out where to store the indexer instance + * @param path to the directory where the packfile should be stored + * @param oid_type the oid type to use for objects + * @return 0 or an error code. + */ +GIT_EXTERN(int) git_indexer_new( + git_indexer **out, + const char *path, + git_oid_t oid_type, + git_indexer_options *opts); +#else /** * Create a new indexer instance * @@ -106,6 +134,7 @@ GIT_EXTERN(int) git_indexer_new( unsigned int mode, git_odb *odb, git_indexer_options *opts); +#endif /** * Add data to the indexer diff --git a/include/git2/object.h b/include/git2/object.h index 5610a476f..6384aaa6e 100644 --- a/include/git2/object.h +++ b/include/git2/object.h @@ -225,6 +225,7 @@ GIT_EXTERN(int) git_object_peel( */ GIT_EXTERN(int) git_object_dup(git_object **dest, git_object *source); +#ifdef GIT_EXPERIMENTAL_SHA256 /** * Analyzes a buffer of raw object content and determines its validity. * Tree, commit, and tag objects will be parsed and ensured that they @@ -238,14 +239,39 @@ GIT_EXTERN(int) git_object_dup(git_object **dest, git_object *source); * @param valid Output pointer to set with validity of the object content * @param buf The contents to validate * @param len The length of the buffer - * @param type The type of the object in the buffer + * @param object_type The type of the object in the buffer + * @param oid_type The object ID type for the OIDs in the given buffer * @return 0 on success or an error code */ GIT_EXTERN(int) git_object_rawcontent_is_valid( int *valid, const char *buf, size_t len, - git_object_t type); + git_object_t object_type, + git_oid_t oid_type); +#else +/** + * Analyzes a buffer of raw object content and determines its validity. + * Tree, commit, and tag objects will be parsed and ensured that they + * are valid, parseable content. (Blobs are always valid by definition.) + * An error message will be set with an informative message if the object + * is not valid. + * + * @warning This function is experimental and its signature may change in + * the future. + * + * @param valid Output pointer to set with validity of the object content + * @param buf The contents to validate + * @param len The length of the buffer + * @param object_type The type of the object in the buffer + * @return 0 on success or an error code + */ +GIT_EXTERN(int) git_object_rawcontent_is_valid( + int *valid, + const char *buf, + size_t len, + git_object_t object_type); +#endif /** @} */ GIT_END_DECL diff --git a/include/git2/odb.h b/include/git2/odb.h index 0ffe3f328..c7d6a894c 100644 --- a/include/git2/odb.h +++ b/include/git2/odb.h @@ -38,6 +38,25 @@ typedef enum { */ typedef int GIT_CALLBACK(git_odb_foreach_cb)(const git_oid *id, void *payload); +/** Options for configuring a loose object backend. */ +typedef struct { + unsigned int version; /**< version for the struct */ + + /** + * Type of object IDs to use for this object database, or + * 0 for default (currently SHA1). + */ + git_oid_t oid_type; +} git_odb_options; + +/* The current version of the diff options structure */ +#define GIT_ODB_OPTIONS_VERSION 1 + +/* Stack initializer for odb options. Alternatively use + * `git_odb_options_init` programmatic initialization. + */ +#define GIT_ODB_OPTIONS_INIT { GIT_ODB_OPTIONS_VERSION } + /** * Create a new object database with no backends. * @@ -46,9 +65,14 @@ typedef int GIT_CALLBACK(git_odb_foreach_cb)(const git_oid *id, void *payload); * * @param out location to store the database pointer, if opened. * Set to NULL if the open failed. + * @param opts the options for this object database or NULL for defaults * @return 0 or an error code */ +#ifdef GIT_EXPERIMENTAL_SHA256 +GIT_EXTERN(int) git_odb_new(git_odb **out, const git_odb_options *opts); +#else GIT_EXTERN(int) git_odb_new(git_odb **out); +#endif /** * Create a new object database and automatically add @@ -64,9 +88,17 @@ GIT_EXTERN(int) git_odb_new(git_odb **out); * @param out location to store the database pointer, if opened. * Set to NULL if the open failed. * @param objects_dir path of the backends' "objects" directory. + * @param opts the options for this object database or NULL for defaults * @return 0 or an error code */ +#ifdef GIT_EXPERIMENTAL_SHA256 +GIT_EXTERN(int) git_odb_open( + git_odb **out, + const char *objects_dir, + const git_odb_options *opts); +#else GIT_EXTERN(int) git_odb_open(git_odb **out, const char *objects_dir); +#endif /** * Add an on-disk alternate to an existing Object DB. @@ -117,7 +149,7 @@ GIT_EXTERN(int) git_odb_read(git_odb_object **out, git_odb *db, const git_oid *i * This method queries all available ODB backends * trying to match the 'len' first hexadecimal * characters of the 'short_id'. - * The remaining (GIT_OID_HEXSZ-len)*4 bits of + * The remaining (GIT_OID_SHA1_HEXSIZE-len)*4 bits of * 'short_id' must be 0s. * 'len' must be at least GIT_OID_MINPREFIXLEN, * and the prefix must be long enough to identify @@ -218,7 +250,7 @@ typedef struct git_odb_expand_id { * * The given array will be updated in place: for each abbreviated ID that is * unique in the database, and of the given type (if specified), - * the full object ID, object ID length (`GIT_OID_HEXSZ`) and type will be + * the full object ID, object ID length (`GIT_OID_SHA1_HEXSIZE`) and type will be * written back to the array. For IDs that are not found (or are ambiguous), * the array entry will be zeroed. * @@ -435,18 +467,28 @@ GIT_EXTERN(int) git_odb_write_multi_pack_index( git_odb *db); /** - * Determine the object-ID (sha1 hash) of a data buffer + * Determine the object-ID (sha1 or sha256 hash) of a data buffer * - * The resulting SHA-1 OID will be the identifier for the data - * buffer as if the data buffer it were to written to the ODB. + * The resulting OID will be the identifier for the data buffer as if + * the data buffer it were to written to the ODB. * * @param out the resulting object-ID. * @param data data to hash * @param len size of the data - * @param type of the data to hash + * @param object_type of the data to hash + * @param oid_type the oid type to hash to * @return 0 or an error code */ +#ifdef GIT_EXPERIMENTAL_SHA256 +GIT_EXTERN(int) git_odb_hash( + git_oid *out, + const void *data, + size_t len, + git_object_t object_type, + git_oid_t oid_type); +#else GIT_EXTERN(int) git_odb_hash(git_oid *out, const void *data, size_t len, git_object_t type); +#endif /** * Read a file from disk and fill a git_oid with the object id @@ -458,10 +500,19 @@ GIT_EXTERN(int) git_odb_hash(git_oid *out, const void *data, size_t len, git_obj * * @param out oid structure the result is written into. * @param path file to read and determine object id for - * @param type the type of the object that will be hashed + * @param object_type of the data to hash + * @param oid_type the oid type to hash to * @return 0 or an error code */ +#ifdef GIT_EXPERIMENTAL_SHA256 +GIT_EXTERN(int) git_odb_hashfile( + git_oid *out, + const char *path, + git_object_t object_type, + git_oid_t oid_type); +#else GIT_EXTERN(int) git_odb_hashfile(git_oid *out, const char *path, git_object_t type); +#endif /** * Create a copy of an odb_object diff --git a/include/git2/odb_backend.h b/include/git2/odb_backend.h index 5ad777b17..12dd0fd38 100644 --- a/include/git2/odb_backend.h +++ b/include/git2/odb_backend.h @@ -24,6 +24,26 @@ GIT_BEGIN_DECL * Constructors for in-box ODB backends. */ +/** Options for configuring a packfile object backend. */ +typedef struct { + unsigned int version; /**< version for the struct */ + + /** + * Type of object IDs to use for this object database, or + * 0 for default (currently SHA1). + */ + git_oid_t oid_type; +} git_odb_backend_pack_options; + +/* The current version of the diff options structure */ +#define GIT_ODB_BACKEND_PACK_OPTIONS_VERSION 1 + +/* Stack initializer for odb pack backend options. Alternatively use + * `git_odb_backend_pack_options_init` programmatic initialization. + */ +#define GIT_ODB_BACKEND_PACK_OPTIONS_INIT \ + { GIT_ODB_BACKEND_PACK_OPTIONS_VERSION } + /** * Create a backend for the packfiles. * @@ -32,27 +52,16 @@ GIT_BEGIN_DECL * * @return 0 or an error code */ -GIT_EXTERN(int) git_odb_backend_pack(git_odb_backend **out, const char *objects_dir); - -/** - * Create a backend for loose objects - * - * @param out location to store the odb backend pointer - * @param objects_dir the Git repository's objects directory - * @param compression_level zlib compression level to use - * @param do_fsync whether to do an fsync() after writing - * @param dir_mode permissions to use creating a directory or 0 for defaults - * @param file_mode permissions to use creating a file or 0 for defaults - * - * @return 0 or an error code - */ -GIT_EXTERN(int) git_odb_backend_loose( +#ifdef GIT_EXPERIMENTAL_SHA256 +GIT_EXTERN(int) git_odb_backend_pack( git_odb_backend **out, const char *objects_dir, - int compression_level, - int do_fsync, - unsigned int dir_mode, - unsigned int file_mode); + const git_odb_backend_pack_options *opts); +#else +GIT_EXTERN(int) git_odb_backend_pack( + git_odb_backend **out, + const char *objects_dir); +#endif /** * Create a backend out of a single packfile @@ -65,7 +74,82 @@ GIT_EXTERN(int) git_odb_backend_loose( * * @return 0 or an error code */ -GIT_EXTERN(int) git_odb_backend_one_pack(git_odb_backend **out, const char *index_file); +#ifdef GIT_EXPERIMENTAL_SHA256 +GIT_EXTERN(int) git_odb_backend_one_pack( + git_odb_backend **out, + const char *index_file, + const git_odb_backend_pack_options *opts); +#else +GIT_EXTERN(int) git_odb_backend_one_pack( + git_odb_backend **out, + const char *index_file); +#endif + +typedef enum { + GIT_ODB_BACKEND_LOOSE_FSYNC = (1 << 0) +} git_odb_backend_loose_flag_t; + +/** Options for configuring a loose object backend. */ +typedef struct { + unsigned int version; /**< version for the struct */ + + /** A combination of the `git_odb_backend_loose_flag_t` types. */ + uint32_t flags; + + /** + * zlib compression level to use (0-9), where 1 is the fastest + * at the expense of larger files, and 9 produces the best + * compression at the expense of speed. 0 indicates that no + * compression should be performed. -1 is the default (currently + * optimizing for speed). + */ + int compression_level; + + /** Permissions to use creating a directory or 0 for defaults */ + unsigned int dir_mode; + + /** Permissions to use creating a file or 0 for defaults */ + unsigned int file_mode; + + /** + * Type of object IDs to use for this object database, or + * 0 for default (currently SHA1). + */ + git_oid_t oid_type; +} git_odb_backend_loose_options; + +/* The current version of the diff options structure */ +#define GIT_ODB_BACKEND_LOOSE_OPTIONS_VERSION 1 + +/* Stack initializer for odb loose backend options. Alternatively use + * `git_odb_backend_loose_options_init` programmatic initialization. + */ +#define GIT_ODB_BACKEND_LOOSE_OPTIONS_INIT \ + { GIT_ODB_BACKEND_LOOSE_OPTIONS_VERSION, 0, -1 } + +/** + * Create a backend for loose objects + * + * @param out location to store the odb backend pointer + * @param objects_dir the Git repository's objects directory + * @param opts options for the loose object backend or NULL + * + * @return 0 or an error code + */ +#ifdef GIT_EXPERIMENTAL_SHA256 +GIT_EXTERN(int) git_odb_backend_loose( + git_odb_backend **out, + const char *objects_dir, + git_odb_backend_loose_options *opts); +#else +GIT_EXTERN(int) git_odb_backend_loose( + git_odb_backend **out, + const char *objects_dir, + int compression_level, + int do_fsync, + unsigned int dir_mode, + unsigned int file_mode); +#endif /** Streaming mode */ typedef enum { @@ -87,6 +171,10 @@ struct git_odb_stream { unsigned int mode; void *hash_ctx; +#ifdef GIT_EXPERIMENTAL_SHA256 + git_oid_t oid_type; +#endif + git_object_size_t declared_size; git_object_size_t received_bytes; diff --git a/include/git2/oid.h b/include/git2/oid.h index 549df4eab..399b7b907 100644 --- a/include/git2/oid.h +++ b/include/git2/oid.h @@ -9,6 +9,7 @@ #include "common.h" #include "types.h" +#include "experimental.h" /** * @file git2/oid.h @@ -19,11 +20,76 @@ */ GIT_BEGIN_DECL -/** Size (in bytes) of a raw/binary oid */ -#define GIT_OID_RAWSZ 20 +/** The type of object id. */ +typedef enum { -/** Size (in bytes) of a hex formatted oid */ -#define GIT_OID_HEXSZ (GIT_OID_RAWSZ * 2) +#ifdef GIT_EXPERIMENTAL_SHA256 + GIT_OID_SHA1 = 1, /**< SHA1 */ + GIT_OID_SHA256 = 2 /**< SHA256 */ +#else + GIT_OID_SHA1 = 1 /**< SHA1 */ +#endif + +} git_oid_t; + +/* + * SHA1 is currently the only supported object ID type. + */ + +/** SHA1 is currently libgit2's default oid type. */ +#define GIT_OID_DEFAULT GIT_OID_SHA1 + +/** Size (in bytes) of a raw/binary sha1 oid */ +#define GIT_OID_SHA1_SIZE 20 +/** Size (in bytes) of a hex formatted sha1 oid */ +#define GIT_OID_SHA1_HEXSIZE (GIT_OID_SHA1_SIZE * 2) + +/** + * The binary representation of the null sha1 object ID. + */ +#ifndef GIT_EXPERIMENTAL_SHA256 +# define GIT_OID_SHA1_ZERO { { 0 } } +#else +# define GIT_OID_SHA1_ZERO { GIT_OID_SHA1, { 0 } } +#endif + +/** + * The string representation of the null sha1 object ID. + */ +#define GIT_OID_SHA1_HEXZERO "0000000000000000000000000000000000000000" + +/* + * Experimental SHA256 support is a breaking change to the API. + * This exists for application compatibility testing. + */ + +#ifdef GIT_EXPERIMENTAL_SHA256 + +/** Size (in bytes) of a raw/binary sha256 oid */ +# define GIT_OID_SHA256_SIZE 32 +/** Size (in bytes) of a hex formatted sha256 oid */ +# define GIT_OID_SHA256_HEXSIZE (GIT_OID_SHA256_SIZE * 2) + +/** + * The binary representation of the null sha256 object ID. + */ +# define GIT_OID_SHA256_ZERO { GIT_OID_SHA256, { 0 } } + +/** + * The string representation of the null sha256 object ID. + */ +# define GIT_OID_SHA256_HEXZERO "0000000000000000000000000000000000000000000000000000000000000000" + +#endif + +/* Maximum possible object ID size in raw / hex string format. */ +#ifndef GIT_EXPERIMENTAL_SHA256 +# define GIT_OID_MAX_SIZE GIT_OID_SHA1_SIZE +# define GIT_OID_MAX_HEXSIZE GIT_OID_SHA1_HEXSIZE +#else +# define GIT_OID_MAX_SIZE GIT_OID_SHA256_SIZE +# define GIT_OID_MAX_HEXSIZE GIT_OID_SHA256_HEXSIZE +#endif /** Minimum length (in number of hex characters, * i.e. packets of 4 bits) of an oid prefix */ @@ -31,29 +97,50 @@ GIT_BEGIN_DECL /** Unique identity of any object (commit, tree, blob, tag). */ typedef struct git_oid { + +#ifdef GIT_EXPERIMENTAL_SHA256 + /** type of object id */ + unsigned char type; +#endif + /** raw binary formatted id */ - unsigned char id[GIT_OID_RAWSZ]; + unsigned char id[GIT_OID_MAX_SIZE]; } git_oid; /** * Parse a hex formatted object id into a git_oid. * + * The appropriate number of bytes for the given object ID type will + * be read from the string - 40 bytes for SHA1, 64 bytes for SHA256. + * The given string need not be NUL terminated. + * * @param out oid structure the result is written into. * @param str input hex string; must be pointing at the start of * the hex sequence and have at least the number of bytes - * needed for an oid encoded in hex (40 bytes). + * needed for an oid encoded in hex (40 bytes for sha1, + * 256 bytes for sha256). + * @param type the type of object id * @return 0 or an error code */ +#ifdef GIT_EXPERIMENTAL_SHA256 +GIT_EXTERN(int) git_oid_fromstr(git_oid *out, const char *str, git_oid_t type); +#else GIT_EXTERN(int) git_oid_fromstr(git_oid *out, const char *str); +#endif /** - * Parse a hex formatted null-terminated string into a git_oid. + * Parse a hex formatted NUL-terminated string into a git_oid. * * @param out oid structure the result is written into. * @param str input hex string; must be null-terminated. + * @param type the type of object id * @return 0 or an error code */ +#ifdef GIT_EXPERIMENTAL_SHA256 +GIT_EXTERN(int) git_oid_fromstrp(git_oid *out, const char *str, git_oid_t type); +#else GIT_EXTERN(int) git_oid_fromstrp(git_oid *out, const char *str); +#endif /** * Parse N characters of a hex formatted object id into a git_oid. @@ -64,9 +151,14 @@ GIT_EXTERN(int) git_oid_fromstrp(git_oid *out, const char *str); * @param out oid structure the result is written into. * @param str input hex string of at least size `length` * @param length length of the input string + * @param type the type of object id * @return 0 or an error code */ +#ifdef GIT_EXPERIMENTAL_SHA256 +GIT_EXTERN(int) git_oid_fromstrn(git_oid *out, const char *str, size_t length, git_oid_t type); +#else GIT_EXTERN(int) git_oid_fromstrn(git_oid *out, const char *str, size_t length); +#endif /** * Copy an already raw oid into a git_oid structure. @@ -75,16 +167,21 @@ GIT_EXTERN(int) git_oid_fromstrn(git_oid *out, const char *str, size_t length); * @param raw the raw input bytes to be copied. * @return 0 on success or error code */ +#ifdef GIT_EXPERIMENTAL_SHA256 +GIT_EXTERN(int) git_oid_fromraw(git_oid *out, const unsigned char *raw, git_oid_t type); +#else GIT_EXTERN(int) git_oid_fromraw(git_oid *out, const unsigned char *raw); +#endif /** * Format a git_oid into a hex string. * * @param out output hex string; must be pointing at the start of * the hex sequence and have at least the number of bytes - * needed for an oid encoded in hex (40 bytes). Only the - * oid digits are written; a '\\0' terminator must be added - * by the caller if it is required. + * needed for an oid encoded in hex (40 bytes for SHA1, + * 64 bytes for SHA256). Only the oid digits are written; + * a '\\0' terminator must be added by the caller if it is + * required. * @param id oid structure to format. * @return 0 on success or error code */ @@ -94,7 +191,7 @@ GIT_EXTERN(int) git_oid_fmt(char *out, const git_oid *id); * Format a git_oid into a partial hex string. * * @param out output hex string; you say how many bytes to write. - * If the number of bytes is > GIT_OID_HEXSZ, extra bytes + * If the number of bytes is > GIT_OID_SHA1_HEXSIZE, extra bytes * will be zeroed; if not, a '\0' terminator is NOT added. * @param n number of characters to write into out string * @param id oid structure to format. @@ -110,9 +207,10 @@ GIT_EXTERN(int) git_oid_nfmt(char *out, size_t n, const git_oid *id); * * @param out output hex string; must be pointing at the start of * the hex sequence and have at least the number of bytes - * needed for an oid encoded in hex (41 bytes). Only the - * oid digits are written; a '\\0' terminator must be added - * by the caller if it is required. + * needed for an oid encoded in hex (41 bytes for SHA1, + * 65 bytes for SHA256). Only the oid digits are written; + * a '\\0' terminator must be added by the caller if it + * is required. * @param id oid structure to format. * @return 0 on success, non-zero callback return value, or error code */ @@ -134,7 +232,9 @@ GIT_EXTERN(char *) git_oid_tostr_s(const git_oid *oid); /** * Format a git_oid into a buffer as a hex format c-string. * - * If the buffer is smaller than GIT_OID_HEXSZ+1, then the resulting + * If the buffer is smaller than the size of a hex-formatted oid string + * plus an additional byte (GIT_OID_SHA_HEXSIZE + 1 for SHA1 or + * GIT_OID_SHA256_HEXSIZE + 1 for SHA256), then the resulting * oid c-string will be truncated to n-1 characters (but will still be * NUL-byte terminated). * diff --git a/include/git2/repository.h b/include/git2/repository.h index c87f3c962..560e70ab6 100644 --- a/include/git2/repository.h +++ b/include/git2/repository.h @@ -351,6 +351,15 @@ typedef struct { * pointing to this URL. */ const char *origin_url; + +#ifdef GIT_EXPERIMENTAL_SHA256 + /** + * + * Type of object IDs to use for this repository, or 0 for + * default (currently SHA1). + */ + git_oid_t oid_type; +#endif } git_repository_init_options; #define GIT_REPOSITORY_INIT_OPTIONS_VERSION 1 @@ -456,7 +465,9 @@ GIT_EXTERN(int) git_repository_head_unborn(git_repository *repo); * Check if a repository is empty * * An empty repository has just been initialized and contains no references - * apart from HEAD, which must be pointing to the unborn master branch. + * apart from HEAD, which must be pointing to the unborn master branch, + * or the branch specified for the repository in the `init.defaultBranch` + * configuration variable. * * @param repo Repo to test * @return 1 if the repository is empty, 0 if it isn't, error code @@ -949,6 +960,14 @@ GIT_EXTERN(int) git_repository_ident(const char **name, const char **email, cons */ GIT_EXTERN(int) git_repository_set_ident(git_repository *repo, const char *name, const char *email); +/** + * Gets the object type used by this repository. + * + * @param repo the repository + * @return the object id type + */ +GIT_EXTERN(git_oid_t) git_repository_oid_type(git_repository *repo); + /** @} */ GIT_END_DECL #endif diff --git a/include/git2/stash.h b/include/git2/stash.h index 32e6f9576..dcfc013dc 100644 --- a/include/git2/stash.h +++ b/include/git2/stash.h @@ -44,7 +44,12 @@ typedef enum { * All ignored files are also stashed and then cleaned up from * the working directory */ - GIT_STASH_INCLUDE_IGNORED = (1 << 2) + GIT_STASH_INCLUDE_IGNORED = (1 << 2), + + /** + * All changes in the index and working directory are left intact + */ + GIT_STASH_KEEP_ALL = (1 << 3) } git_stash_flags; /** @@ -52,15 +57,10 @@ typedef enum { * * @param out Object id of the commit containing the stashed state. * This commit is also the target of the direct reference refs/stash. - * * @param repo The owning repository. - * * @param stasher The identity of the person performing the stashing. - * * @param message Optional description along with the stashed state. - * * @param flags Flags to control the stashing process. (see GIT_STASH_* above) - * * @return 0 on success, GIT_ENOTFOUND where there's nothing to stash, * or error code. */ @@ -71,6 +71,60 @@ GIT_EXTERN(int) git_stash_save( const char *message, uint32_t flags); +/** + * Stash save options structure + * + * Initialize with `GIT_STASH_SAVE_OPTIONS_INIT`. Alternatively, you can + * use `git_stash_save_options_init`. + * + */ +typedef struct git_stash_save_options { + unsigned int version; + + /** Flags to control the stashing process. (see GIT_STASH_* above) */ + uint32_t flags; + + /** The identity of the person performing the stashing. */ + const git_signature *stasher; + + /** Optional description along with the stashed state. */ + const char *message; + + /** Optional paths that control which files are stashed. */ + git_strarray paths; +} git_stash_save_options; + +#define GIT_STASH_SAVE_OPTIONS_VERSION 1 +#define GIT_STASH_SAVE_OPTIONS_INIT { GIT_STASH_SAVE_OPTIONS_VERSION } + +/** + * Initialize git_stash_save_options structure + * + * Initializes a `git_stash_save_options` with default values. Equivalent to + * creating an instance with `GIT_STASH_SAVE_OPTIONS_INIT`. + * + * @param opts The `git_stash_save_options` struct to initialize. + * @param version The struct version; pass `GIT_STASH_SAVE_OPTIONS_VERSION`. + * @return Zero on success; -1 on failure. + */ +GIT_EXTERN(int) git_stash_save_options_init( + git_stash_save_options *opts, unsigned int version); + +/** + * Save the local modifications to a new stash, with options. + * + * @param out Object id of the commit containing the stashed state. + * This commit is also the target of the direct reference refs/stash. + * @param repo The owning repository. + * @param opts The stash options. + * @return 0 on success, GIT_ENOTFOUND where there's nothing to stash, + * or error code. + */ +GIT_EXTERN(int) git_stash_save_with_opts( + git_oid *out, + git_repository *repo, + const git_stash_save_options *opts); + /** Stash application flags. */ typedef enum { GIT_STASH_APPLY_DEFAULT = 0, diff --git a/include/git2/strarray.h b/include/git2/strarray.h index 0f657e6c5..03d93f8fb 100644 --- a/include/git2/strarray.h +++ b/include/git2/strarray.h @@ -36,19 +36,6 @@ typedef struct git_strarray { */ GIT_EXTERN(void) git_strarray_dispose(git_strarray *array); -/** - * Copy a string array object from source to target. - * - * Note: target is overwritten and hence should be empty, otherwise its - * contents are leaked. Call git_strarray_free() if necessary. - * - * @param tgt target - * @param src source - * @return 0 on success, < 0 on allocation failure - */ -GIT_EXTERN(int) git_strarray_copy(git_strarray *tgt, const git_strarray *src); - - /** @} */ GIT_END_DECL diff --git a/include/git2/sys/odb_backend.h b/include/git2/sys/odb_backend.h index 8598f94e5..c42abd370 100644 --- a/include/git2/sys/odb_backend.h +++ b/include/git2/sys/odb_backend.h @@ -36,7 +36,7 @@ struct git_odb_backend { void **, size_t *, git_object_t *, git_odb_backend *, const git_oid *); /* To find a unique object given a prefix of its oid. The oid given - * must be so that the remaining (GIT_OID_HEXSZ - len)*4 bits are 0s. + * must be so that the remaining (GIT_OID_SHA1_HEXSIZE - len)*4 bits are 0s. */ int GIT_CALLBACK(read_prefix)( git_oid *, void **, size_t *, git_object_t *, diff --git a/include/git2/sys/transport.h b/include/git2/sys/transport.h index 06ae7079f..b70582188 100644 --- a/include/git2/sys/transport.h +++ b/include/git2/sys/transport.h @@ -57,6 +57,18 @@ struct git_transport { unsigned int *capabilities, git_transport *transport); +#ifdef GIT_EXPERIMENTAL_SHA256 + /** + * Gets the object type for the remote repository. + * + * This function may be called after a successful call to + * `connect()`. + */ + int GIT_CALLBACK(oid_type)( + git_oid_t *object_type, + git_transport *transport); +#endif + /** * Get the list of available references in the remote repository. * diff --git a/include/git2/version.h b/include/git2/version.h index 944d74365..97221e459 100644 --- a/include/git2/version.h +++ b/include/git2/version.h @@ -11,16 +11,16 @@ * The version string for libgit2. This string follows semantic * versioning (v2) guidelines. */ -#define LIBGIT2_VERSION "1.5.1" +#define LIBGIT2_VERSION "1.6.4" /** The major version number for this version of libgit2. */ #define LIBGIT2_VER_MAJOR 1 /** The minor version number for this version of libgit2. */ -#define LIBGIT2_VER_MINOR 5 +#define LIBGIT2_VER_MINOR 6 /** The revision ("teeny") version number for this version of libgit2. */ -#define LIBGIT2_VER_REVISION 1 +#define LIBGIT2_VER_REVISION 4 /** The Windows DLL patch number for this version of libgit2. */ #define LIBGIT2_VER_PATCH 0 @@ -34,6 +34,6 @@ #define LIBGIT2_VER_PRERELEASE NULL /** The library ABI soversion for this version of libgit2. */ -#define LIBGIT2_SOVERSION "1.5" +#define LIBGIT2_SOVERSION "1.6" #endif diff --git a/package.json b/package.json index 8e8176f22..9695f90d9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "libgit2", - "version": "1.5.1", + "version": "1.6.4", "repo": "https://github.com/libgit2/libgit2", "description": " A cross-platform, linkable library implementation of Git that you can use in your application.", "install": "mkdir build && cd build && cmake .. && cmake --build ." diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d16cfe538..e108b2e79 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -170,12 +170,6 @@ if(ICONV_FOUND) endif() add_feature_info(iconv GIT_USE_ICONV "iconv encoding conversion support") -# -# Configure support -# - -configure_file(features.h.in git2/sys/features.h) - # # Include child projects # diff --git a/src/cli/CMakeLists.txt b/src/cli/CMakeLists.txt index 4f347e93f..84b6c1901 100644 --- a/src/cli/CMakeLists.txt +++ b/src/cli/CMakeLists.txt @@ -1,8 +1,10 @@ set(CLI_INCLUDES - "${libgit2_BINARY_DIR}/src" + "${libgit2_BINARY_DIR}/src/util" + "${libgit2_BINARY_DIR}/include" "${libgit2_SOURCE_DIR}/src/util" "${libgit2_SOURCE_DIR}/src/cli" - "${libgit2_SOURCE_DIR}/include") + "${libgit2_SOURCE_DIR}/include" + "${LIBGIT2_DEPENDENCY_INCLUDES}") if(WIN32 AND NOT CYGWIN) file(GLOB CLI_SRC_OS win32/*.c) @@ -39,6 +41,7 @@ target_link_libraries(git2_cli ${CLI_LIBGIT2_LIBRARY} ${LIBGIT2_SYSTEM_LIBS}) set_target_properties(git2_cli PROPERTIES C_STANDARD 90) set_target_properties(git2_cli PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${libgit2_BINARY_DIR}) +set_target_properties(git2_cli PROPERTIES OUTPUT_NAME ${LIBGIT2_FILENAME}) ide_split_sources(git2_cli) diff --git a/src/cli/cmd_hash_object.c b/src/cli/cmd_hash_object.c index 5cfe9146a..93b980d66 100644 --- a/src/cli/cmd_hash_object.c +++ b/src/cli/cmd_hash_object.c @@ -49,23 +49,39 @@ static void print_help(void) cli_opt_help_fprint(stdout, opts); } -static int hash_buf(git_odb *odb, git_str *buf, git_object_t type) +static int hash_buf( + git_odb *odb, + git_str *buf, + git_object_t object_type, + git_oid_t oid_type) { git_oid oid; if (!literally) { int valid = 0; - if (git_object_rawcontent_is_valid(&valid, buf->ptr, buf->size, type) < 0 || !valid) +#ifdef GIT_EXPERIMENTAL_SHA256 + if (git_object_rawcontent_is_valid(&valid, buf->ptr, buf->size, object_type, oid_type) < 0 || !valid) return cli_error_git(); +#else + GIT_UNUSED(oid_type); + + if (git_object_rawcontent_is_valid(&valid, buf->ptr, buf->size, object_type) < 0 || !valid) + return cli_error_git(); +#endif } if (write_object) { - if (git_odb_write(&oid, odb, buf->ptr, buf->size, type) < 0) + if (git_odb_write(&oid, odb, buf->ptr, buf->size, object_type) < 0) return cli_error_git(); } else { - if (git_odb_hash(&oid, buf->ptr, buf->size, type) < 0) +#ifdef GIT_EXPERIMENTAL_SHA256 + if (git_odb_hash(&oid, buf->ptr, buf->size, object_type, GIT_OID_SHA1) < 0) return cli_error_git(); +#else + if (git_odb_hash(&oid, buf->ptr, buf->size, object_type) < 0) + return cli_error_git(); +#endif } if (printf("%s\n", git_oid_tostr_s(&oid)) < 0) @@ -78,9 +94,10 @@ int cmd_hash_object(int argc, char **argv) { git_repository *repo = NULL; git_odb *odb = NULL; + git_oid_t oid_type; git_str buf = GIT_STR_INIT; cli_opt invalid_opt; - git_object_t type = GIT_OBJECT_BLOB; + git_object_t object_type = GIT_OBJECT_BLOB; char **filename; int ret = 0; @@ -92,7 +109,7 @@ int cmd_hash_object(int argc, char **argv) return 0; } - if (type_name && (type = git_object_string2type(type_name)) == GIT_OBJECT_INVALID) + if (type_name && (object_type = git_object_string2type(type_name)) == GIT_OBJECT_INVALID) return cli_error_usage("invalid object type '%s'", type_name); if (write_object && @@ -102,6 +119,8 @@ int cmd_hash_object(int argc, char **argv) goto done; } + oid_type = git_repository_oid_type(repo); + /* * TODO: we're reading blobs, we shouldn't pull them all into main * memory, we should just stream them into the odb instead. @@ -113,7 +132,7 @@ int cmd_hash_object(int argc, char **argv) goto done; } - if ((ret = hash_buf(odb, &buf, type)) != 0) + if ((ret = hash_buf(odb, &buf, object_type, oid_type)) != 0) goto done; } else { for (filename = filenames; *filename; filename++) { @@ -122,7 +141,7 @@ int cmd_hash_object(int argc, char **argv) goto done; } - if ((ret = hash_buf(odb, &buf, type)) != 0) + if ((ret = hash_buf(odb, &buf, object_type, oid_type)) != 0) goto done; } } diff --git a/src/cli/opt.c b/src/cli/opt.c index 72df5877f..62a3430d1 100644 --- a/src/cli/opt.c +++ b/src/cli/opt.c @@ -23,7 +23,7 @@ #include "opt.h" #ifdef _WIN32 -# include +# include #else # include # include diff --git a/src/libgit2/CMakeLists.txt b/src/libgit2/CMakeLists.txt index 0c7ddddba..dcb4279c1 100644 --- a/src/libgit2/CMakeLists.txt +++ b/src/libgit2/CMakeLists.txt @@ -8,21 +8,12 @@ set_target_properties(libgit2 PROPERTIES C_EXTENSIONS OFF) include(PkgBuildConfig) set(LIBGIT2_INCLUDES - "${PROJECT_BINARY_DIR}/src" + "${PROJECT_BINARY_DIR}/src/util" + "${PROJECT_BINARY_DIR}/include" "${PROJECT_SOURCE_DIR}/src/libgit2" "${PROJECT_SOURCE_DIR}/src/util" "${PROJECT_SOURCE_DIR}/include") -if(WIN32 AND EMBED_SSH_PATH) - file(GLOB SRC_SSH "${EMBED_SSH_PATH}/src/*.c") - list(SORT SRC_SSH) - target_sources(libgit2 PRIVATE ${SRC_SSH}) - - list(APPEND LIBGIT2_SYSTEM_INCLUDES "${EMBED_SSH_PATH}/include") - file(WRITE "${EMBED_SSH_PATH}/src/libssh2_config.h" "#define HAVE_WINCNG\n#define LIBSSH2_WINCNG\n#include \"../win32/libssh2_config.h\"") - set(GIT_SSH 1) -endif() - # Collect sourcefiles file(GLOB SRC_H "${PROJECT_SOURCE_DIR}/include/git2.h" @@ -67,6 +58,7 @@ endif() ide_split_sources(libgit2) list(APPEND LIBGIT2_OBJECTS $ $ ${LIBGIT2_DEPENDENCY_OBJECTS}) +list(APPEND LIBGIT2_INCLUDES ${LIBGIT2_DEPENDENCY_INCLUDES}) target_include_directories(libgit2 PRIVATE ${LIBGIT2_INCLUDES} ${LIBGIT2_DEPENDENCY_INCLUDES} PUBLIC ${PROJECT_SOURCE_DIR}/include) target_include_directories(libgit2 SYSTEM PRIVATE ${LIBGIT2_SYSTEM_INCLUDES}) @@ -84,6 +76,7 @@ set(LIBGIT2_SYSTEM_LIBS ${LIBGIT2_SYSTEM_LIBS} PARENT_SCOPE) add_library(libgit2package ${SRC_RC} ${LIBGIT2_OBJECTS}) target_link_libraries(libgit2package ${LIBGIT2_SYSTEM_LIBS}) +target_include_directories(libgit2package SYSTEM PRIVATE ${LIBGIT2_INCLUDES}) set_target_properties(libgit2package PROPERTIES C_STANDARD 90) set_target_properties(libgit2package PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) @@ -109,10 +102,10 @@ if(SONAME) endif() endif() -pkg_build_config(NAME libgit2 +pkg_build_config(NAME "lib${LIBGIT2_FILENAME}" VERSION ${libgit2_VERSION} DESCRIPTION "The git library, take 2" - LIBS_SELF git2 + LIBS_SELF ${LIBGIT2_FILENAME} PRIVATE_LIBS ${LIBGIT2_PC_LIBS} REQUIRES ${LIBGIT2_PC_REQUIRES}) @@ -122,10 +115,26 @@ if(MSVC_IDE) set_source_files_properties(win32/precompiled.c COMPILE_FLAGS "/Ycprecompiled.h") endif() +# support experimental features and functionality + +configure_file(experimental.h.in "${PROJECT_BINARY_DIR}/include/git2/experimental.h") + +# translate filenames in the git2.h so that they match the install directory +# (allows for side-by-side installs of libgit2 and libgit2-experimental.) + +FILE(READ "${PROJECT_SOURCE_DIR}/include/git2.h" LIBGIT2_INCLUDE) +STRING(REGEX REPLACE "#include \"git2\/" "#include \"${LIBGIT2_FILENAME}/" LIBGIT2_INCLUDE "${LIBGIT2_INCLUDE}") +FILE(WRITE "${PROJECT_BINARY_DIR}/include/${LIBGIT2_FILENAME}.h" ${LIBGIT2_INCLUDE}) + # Install + install(TARGETS libgit2package RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) -install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/git2 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) -install(FILES ${PROJECT_SOURCE_DIR}/include/git2.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/git2/ + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${LIBGIT2_FILENAME}") +install(FILES ${PROJECT_BINARY_DIR}/include/git2/experimental.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${LIBGIT2_FILENAME}") +install(FILES "${PROJECT_BINARY_DIR}/include/${LIBGIT2_FILENAME}.h" + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) diff --git a/src/libgit2/annotated_commit.c b/src/libgit2/annotated_commit.c index e48947679..7bd8b6077 100644 --- a/src/libgit2/annotated_commit.c +++ b/src/libgit2/annotated_commit.c @@ -40,7 +40,7 @@ static int annotated_commit_init( goto done; git_oid_fmt(annotated_commit->id_str, git_commit_id(commit)); - annotated_commit->id_str[GIT_OID_HEXSZ] = '\0'; + annotated_commit->id_str[GIT_OID_SHA1_HEXSIZE] = '\0'; if (!description) description = annotated_commit->id_str; diff --git a/src/libgit2/annotated_commit.h b/src/libgit2/annotated_commit.h index 444a2ed10..c87eaa805 100644 --- a/src/libgit2/annotated_commit.h +++ b/src/libgit2/annotated_commit.h @@ -41,7 +41,7 @@ struct git_annotated_commit { const char *ref_name; const char *remote_url; - char id_str[GIT_OID_HEXSZ+1]; + char id_str[GIT_OID_SHA1_HEXSIZE+1]; }; extern int git_annotated_commit_from_head(git_annotated_commit **out, diff --git a/src/libgit2/attr_file.c b/src/libgit2/attr_file.c index 0eb881a9b..afa8ec7b3 100644 --- a/src/libgit2/attr_file.c +++ b/src/libgit2/attr_file.c @@ -135,7 +135,7 @@ int git_attr_file__load( break; case GIT_ATTR_FILE_SOURCE_INDEX: { if ((error = attr_file_oid_from_index(&id, repo, entry->path)) < 0 || - (error = git_blob_lookup(&blob, repo, &id)) < 0) + (error = git_blob_lookup(&blob, repo, &id)) < 0) return error; /* Do not assume that data straight from the ODB is NULL-terminated; diff --git a/src/libgit2/attrcache.c b/src/libgit2/attrcache.c index b16d95c3c..405944ed1 100644 --- a/src/libgit2/attrcache.c +++ b/src/libgit2/attrcache.c @@ -300,7 +300,7 @@ static int attr_cache__lookup_path( /* expand leading ~/ as needed */ if (cfgval && cfgval[0] == '~' && cfgval[1] == '/') { - if (! (error = git_sysdir_expand_global_file(&buf, &cfgval[2]))) + if (! (error = git_sysdir_expand_homedir_file(&buf, &cfgval[2]))) *out = git_str_detach(&buf); } else if (cfgval) { *out = git__strdup(cfgval); diff --git a/src/libgit2/blame.c b/src/libgit2/blame.c index a6ab43efd..b70cd615e 100644 --- a/src/libgit2/blame.c +++ b/src/libgit2/blame.c @@ -72,6 +72,8 @@ static git_blame_hunk *new_hunk( hunk->final_start_line_number = start; hunk->orig_start_line_number = orig_start; hunk->orig_path = path ? git__strdup(path) : NULL; + git_oid_clear(&hunk->orig_commit_id, GIT_OID_SHA1); + git_oid_clear(&hunk->final_commit_id, GIT_OID_SHA1); return hunk; } diff --git a/src/libgit2/blob.c b/src/libgit2/blob.c index b1680d3a8..5cfd7474b 100644 --- a/src/libgit2/blob.c +++ b/src/libgit2/blob.c @@ -52,11 +52,12 @@ void git_blob__free(void *_blob) git__free(blob); } -int git_blob__parse_raw(void *_blob, const char *data, size_t size) +int git_blob__parse_raw(void *_blob, const char *data, size_t size, git_oid_t oid_type) { git_blob *blob = (git_blob *) _blob; GIT_ASSERT_ARG(blob); + GIT_UNUSED(oid_type); blob->raw = 1; blob->data.raw.data = data; @@ -64,11 +65,12 @@ int git_blob__parse_raw(void *_blob, const char *data, size_t size) return 0; } -int git_blob__parse(void *_blob, git_odb_object *odb_obj) +int git_blob__parse(void *_blob, git_odb_object *odb_obj, git_oid_t oid_type) { git_blob *blob = (git_blob *) _blob; GIT_ASSERT_ARG(blob); + GIT_UNUSED(oid_type); git_cached_obj_incref((git_cached_obj *)odb_obj); blob->raw = 0; diff --git a/src/libgit2/blob.h b/src/libgit2/blob.h index 9a5dda225..d6c9dd99b 100644 --- a/src/libgit2/blob.h +++ b/src/libgit2/blob.h @@ -36,8 +36,8 @@ struct git_blob { } while(0) void git_blob__free(void *blob); -int git_blob__parse(void *blob, git_odb_object *obj); -int git_blob__parse_raw(void *blob, const char *data, size_t size); +int git_blob__parse(void *blob, git_odb_object *obj, git_oid_t oid_type); +int git_blob__parse_raw(void *blob, const char *data, size_t size, git_oid_t oid_type); int git_blob__getbuf(git_str *buffer, git_blob *blob); extern int git_blob__create_from_paths( diff --git a/src/libgit2/branch.c b/src/libgit2/branch.c index 2dd7d2bb4..4cbd1e26f 100644 --- a/src/libgit2/branch.c +++ b/src/libgit2/branch.c @@ -134,9 +134,9 @@ int git_branch_create( const git_commit *commit, int force) { - char commit_id[GIT_OID_HEXSZ + 1]; + char commit_id[GIT_OID_SHA1_HEXSIZE + 1]; - git_oid_tostr(commit_id, GIT_OID_HEXSZ + 1, git_commit_id(commit)); + git_oid_tostr(commit_id, GIT_OID_SHA1_HEXSIZE + 1, git_commit_id(commit)); return create_branch(ref_out, repository, branch_name, commit, commit_id, force); } diff --git a/src/libgit2/cherrypick.c b/src/libgit2/cherrypick.c index 9ec4962b9..04812b1c6 100644 --- a/src/libgit2/cherrypick.c +++ b/src/libgit2/cherrypick.c @@ -106,10 +106,10 @@ static int cherrypick_state_cleanup(git_repository *repo) static int cherrypick_seterr(git_commit *commit, const char *fmt) { - char commit_oidstr[GIT_OID_HEXSZ + 1]; + char commit_oidstr[GIT_OID_SHA1_HEXSIZE + 1]; git_error_set(GIT_ERROR_CHERRYPICK, fmt, - git_oid_tostr(commit_oidstr, GIT_OID_HEXSZ + 1, git_commit_id(commit))); + git_oid_tostr(commit_oidstr, GIT_OID_SHA1_HEXSIZE + 1, git_commit_id(commit))); return -1; } @@ -173,7 +173,7 @@ int git_cherrypick( git_cherrypick_options opts; git_reference *our_ref = NULL; git_commit *our_commit = NULL; - char commit_oidstr[GIT_OID_HEXSZ + 1]; + char commit_oidstr[GIT_OID_SHA1_HEXSIZE + 1]; const char *commit_msg, *commit_summary; git_str their_label = GIT_STR_INIT; git_index *index = NULL; diff --git a/src/libgit2/clone.c b/src/libgit2/clone.c index 1843875f8..b73880e44 100644 --- a/src/libgit2/clone.c +++ b/src/libgit2/clone.c @@ -282,7 +282,11 @@ static int update_head_to_branch( reflog_message)) < 0) goto cleanup; - if ((retcode = git_remote__default_branch(&default_branch, remote)) < 0) + retcode = git_remote__default_branch(&default_branch, remote); + + if (retcode == GIT_ENOTFOUND) + retcode = 0; + else if (retcode) goto cleanup; if (!git_remote__matching_refspec(remote, git_str_cstr(&default_branch))) @@ -389,12 +393,19 @@ static int checkout_branch(git_repository *repo, git_remote *remote, const git_c return error; } -static int clone_into(git_repository *repo, git_remote *_remote, const git_fetch_options *opts, const git_checkout_options *co_opts, const char *branch) +static int clone_into( + git_repository *repo, + git_remote *_remote, + const git_fetch_options *opts, + const git_checkout_options *co_opts, + const char *branch) { int error; git_str reflog_message = GIT_STR_INIT; + git_remote_connect_options connect_opts = GIT_REMOTE_CONNECT_OPTIONS_INIT; git_fetch_options fetch_opts; git_remote *remote; + git_oid_t oid_type; GIT_ASSERT_ARG(repo); GIT_ASSERT_ARG(_remote); @@ -410,8 +421,25 @@ static int clone_into(git_repository *repo, git_remote *_remote, const git_fetch memcpy(&fetch_opts, opts, sizeof(git_fetch_options)); fetch_opts.update_fetchhead = 0; fetch_opts.download_tags = GIT_REMOTE_DOWNLOAD_TAGS_ALL; + + if ((error = git_remote_connect_options__from_fetch_opts(&connect_opts, remote, &fetch_opts)) < 0) + goto cleanup; + git_str_printf(&reflog_message, "clone: from %s", git_remote_url(remote)); + /* + * Connect to the server so that we can identify the remote + * object format. + */ + + if ((error = git_remote_connect_ext(remote, GIT_DIRECTION_FETCH, + &connect_opts)) < 0) + goto cleanup; + + if ((error = git_remote_oid_type(&oid_type, remote)) < 0 || + (error = git_repository__set_objectformat(repo, oid_type)) < 0) + goto cleanup; + if ((error = git_remote_fetch(remote, NULL, &fetch_opts, git_str_cstr(&reflog_message))) != 0) goto cleanup; @@ -419,6 +447,7 @@ static int clone_into(git_repository *repo, git_remote *_remote, const git_fetch cleanup: git_remote_free(remote); + git_remote_connect_options_dispose(&connect_opts); git_str_dispose(&reflog_message); return error; diff --git a/src/libgit2/commit.c b/src/libgit2/commit.c index b137463f3..d85fefb3d 100644 --- a/src/libgit2/commit.c +++ b/src/libgit2/commit.c @@ -56,11 +56,13 @@ static int git_commit__create_buffer_internal( GIT_ASSERT_ARG(out); GIT_ASSERT_ARG(tree); - git_oid__writebuf(out, "tree ", tree); + if (git_object__write_oid_header(out, "tree ", tree) < 0) + goto on_error; for (i = 0; i < git_array_size(*parents); i++) { parent = git_array_get(*parents, i); - git_oid__writebuf(out, "parent ", parent); + if (git_object__write_oid_header(out, "parent ", parent) < 0) + goto on_error; } git_signature__writebuf(out, "author ", author); @@ -388,7 +390,11 @@ int git_commit_amend( return error; } -static int commit_parse(git_commit *commit, const char *data, size_t size, unsigned int flags) +static int commit_parse( + git_commit *commit, + const char *data, + size_t size, + git_commit__parse_options *opts) { const char *buffer_start = data, *buffer; const char *buffer_end = buffer_start + size; @@ -399,6 +405,7 @@ static int commit_parse(git_commit *commit, const char *data, size_t size, unsig GIT_ASSERT_ARG(commit); GIT_ASSERT_ARG(data); + GIT_ASSERT_ARG(opts); buffer = buffer_start; @@ -407,11 +414,14 @@ static int commit_parse(git_commit *commit, const char *data, size_t size, unsig GIT_ERROR_CHECK_ARRAY(commit->parent_ids); /* The tree is always the first field */ - if (!(flags & GIT_COMMIT_PARSE_QUICK)) { - if (git_oid__parse(&commit->tree_id, &buffer, buffer_end, "tree ") < 0) + if (!(opts->flags & GIT_COMMIT_PARSE_QUICK)) { + if (git_object__parse_oid_header(&commit->tree_id, + &buffer, buffer_end, "tree ", + opts->oid_type) < 0) goto bad_buffer; } else { - size_t tree_len = strlen("tree ") + GIT_OID_HEXSZ + 1; + size_t tree_len = strlen("tree ") + git_oid_hexsize(opts->oid_type) + 1; + if (buffer + tree_len > buffer_end) goto bad_buffer; buffer += tree_len; @@ -421,14 +431,16 @@ static int commit_parse(git_commit *commit, const char *data, size_t size, unsig * TODO: commit grafts! */ - while (git_oid__parse(&parent_id, &buffer, buffer_end, "parent ") == 0) { + while (git_object__parse_oid_header(&parent_id, + &buffer, buffer_end, "parent ", + opts->oid_type) == 0) { git_oid *new_id = git_array_alloc(commit->parent_ids); GIT_ERROR_CHECK_ALLOC(new_id); git_oid_cpy(new_id, &parent_id); } - if (!(flags & GIT_COMMIT_PARSE_QUICK)) { + if (!opts || !(opts->flags & GIT_COMMIT_PARSE_QUICK)) { commit->author = git__malloc(sizeof(git_signature)); GIT_ERROR_CHECK_ALLOC(commit->author); @@ -452,7 +464,7 @@ static int commit_parse(git_commit *commit, const char *data, size_t size, unsig if ((error = git_signature__parse(commit->committer, &buffer, buffer_end, "committer ", '\n')) < 0) return error; - if (flags & GIT_COMMIT_PARSE_QUICK) + if (opts && opts->flags & GIT_COMMIT_PARSE_QUICK) return 0; /* Parse add'l header entries */ @@ -497,19 +509,39 @@ bad_buffer: return GIT_EINVALID; } -int git_commit__parse_raw(void *commit, const char *data, size_t size) +int git_commit__parse( + void *commit, + git_odb_object *odb_obj, + git_oid_t oid_type) { - return commit_parse(commit, data, size, 0); + git_commit__parse_options parse_options = {0}; + parse_options.oid_type = oid_type; + + return git_commit__parse_ext(commit, odb_obj, &parse_options); } -int git_commit__parse_ext(git_commit *commit, git_odb_object *odb_obj, unsigned int flags) +int git_commit__parse_raw( + void *commit, + const char *data, + size_t size, + git_oid_t oid_type) { - return commit_parse(commit, git_odb_object_data(odb_obj), git_odb_object_size(odb_obj), flags); + git_commit__parse_options parse_options = {0}; + parse_options.oid_type = oid_type; + + return commit_parse(commit, data, size, &parse_options); } -int git_commit__parse(void *_commit, git_odb_object *odb_obj) +int git_commit__parse_ext( + git_commit *commit, + git_odb_object *odb_obj, + git_commit__parse_options *parse_opts) { - return git_commit__parse_ext(_commit, odb_obj, 0); + return commit_parse( + commit, + git_odb_object_data(odb_obj), + git_odb_object_size(odb_obj), + parse_opts); } #define GIT_COMMIT_GETTER(_rvalue, _name, _return, _invalid) \ @@ -566,7 +598,7 @@ const char *git_commit_summary(git_commit *commit) while (*next && git__isspace_nonlf(*next)) { ++next; } - if (!*next || *next == '\n') + if (!*next || *next == '\n') break; } /* record the beginning of contiguous whitespace runs */ @@ -979,11 +1011,14 @@ int git_commit_create_with_signature( git_str commit = GIT_STR_INIT; git_commit *parsed; git_array_oid_t parents = GIT_ARRAY_INIT; + git_commit__parse_options parse_opts = {0}; + + parse_opts.oid_type = repo->oid_type; /* The first step is to verify that all the tree and parents exist */ parsed = git__calloc(1, sizeof(git_commit)); GIT_ERROR_CHECK_ALLOC(parsed); - if (commit_parse(parsed, commit_content, strlen(commit_content), 0) < 0) { + if (commit_parse(parsed, commit_content, strlen(commit_content), &parse_opts) < 0) { error = -1; goto cleanup; } diff --git a/src/libgit2/commit.h b/src/libgit2/commit.h index 7a2454e61..c25fee327 100644 --- a/src/libgit2/commit.h +++ b/src/libgit2/commit.h @@ -33,6 +33,16 @@ struct git_commit { char *body; }; +typedef struct { + git_oid_t oid_type; + unsigned int flags; +} git_commit__parse_options; + +typedef enum { + /** Only parse parents and committer info */ + GIT_COMMIT_PARSE_QUICK = (1 << 0) +} git_commit__parse_flags; + int git_commit__header_field( git_str *out, const git_commit *commit, @@ -56,14 +66,22 @@ int git_commit__create_buffer( size_t parent_count, const git_commit *parents[]); +int git_commit__parse( + void *commit, + git_odb_object *obj, + git_oid_t oid_type); + +int git_commit__parse_raw( + void *commit, + const char *data, + size_t size, + git_oid_t oid_type); + +int git_commit__parse_ext( + git_commit *commit, + git_odb_object *odb_obj, + git_commit__parse_options *parse_opts); + void git_commit__free(void *commit); -int git_commit__parse(void *commit, git_odb_object *obj); -int git_commit__parse_raw(void *commit, const char *data, size_t size); - -typedef enum { - GIT_COMMIT_PARSE_QUICK = (1 << 0) /**< Only parse parents and committer info */ -} git_commit__parse_flags; - -int git_commit__parse_ext(git_commit *commit, git_odb_object *odb_obj, unsigned int flags); #endif diff --git a/src/libgit2/commit_graph.c b/src/libgit2/commit_graph.c index 10947acec..bf557f7ad 100644 --- a/src/libgit2/commit_graph.c +++ b/src/libgit2/commit_graph.c @@ -138,19 +138,19 @@ static int commit_graph_parse_oid_lookup( struct git_commit_graph_chunk *chunk_oid_lookup) { uint32_t i; - unsigned char *oid, *prev_oid, zero_oid[GIT_OID_RAWSZ] = {0}; + unsigned char *oid, *prev_oid, zero_oid[GIT_OID_SHA1_SIZE] = {0}; if (chunk_oid_lookup->offset == 0) return commit_graph_error("missing OID Lookup chunk"); if (chunk_oid_lookup->length == 0) return commit_graph_error("empty OID Lookup chunk"); - if (chunk_oid_lookup->length != file->num_commits * GIT_OID_RAWSZ) + if (chunk_oid_lookup->length != file->num_commits * GIT_OID_SHA1_SIZE) return commit_graph_error("OID Lookup chunk has wrong length"); file->oid_lookup = oid = (unsigned char *)(data + chunk_oid_lookup->offset); prev_oid = zero_oid; - for (i = 0; i < file->num_commits; ++i, oid += GIT_OID_RAWSZ) { - if (git_oid_raw_cmp(prev_oid, oid) >= 0) + for (i = 0; i < file->num_commits; ++i, oid += GIT_OID_SHA1_SIZE) { + if (git_oid_raw_cmp(prev_oid, oid, GIT_OID_SHA1_SIZE) >= 0) return commit_graph_error("OID Lookup index is non-monotonic"); prev_oid = oid; } @@ -167,7 +167,7 @@ static int commit_graph_parse_commit_data( return commit_graph_error("missing Commit Data chunk"); if (chunk_commit_data->length == 0) return commit_graph_error("empty Commit Data chunk"); - if (chunk_commit_data->length != file->num_commits * (GIT_OID_RAWSZ + 16)) + if (chunk_commit_data->length != file->num_commits * (GIT_OID_SHA1_SIZE + 16)) return commit_graph_error("Commit Data chunk has wrong length"); file->commit_data = data + chunk_commit_data->offset; @@ -200,8 +200,7 @@ int git_commit_graph_file_parse( const unsigned char *chunk_hdr; struct git_commit_graph_chunk *last_chunk; uint32_t i; - off64_t last_chunk_offset, chunk_offset, trailer_offset; - unsigned char checksum[GIT_HASH_SHA1_SIZE]; + uint64_t last_chunk_offset, chunk_offset, trailer_offset; size_t checksum_size; int error; struct git_commit_graph_chunk chunk_oid_fanout = {0}, chunk_oid_lookup = {0}, @@ -210,7 +209,7 @@ int git_commit_graph_file_parse( GIT_ASSERT_ARG(file); - if (size < sizeof(struct git_commit_graph_header) + GIT_OID_RAWSZ) + if (size < sizeof(struct git_commit_graph_header) + GIT_OID_SHA1_SIZE) return commit_graph_error("commit-graph is too short"); hdr = ((struct git_commit_graph_header *)data); @@ -227,23 +226,18 @@ int git_commit_graph_file_parse( * headers, and a special zero chunk. */ last_chunk_offset = sizeof(struct git_commit_graph_header) + (1 + hdr->chunks) * 12; - trailer_offset = size - GIT_OID_RAWSZ; + trailer_offset = size - GIT_OID_SHA1_SIZE; checksum_size = GIT_HASH_SHA1_SIZE; if (trailer_offset < last_chunk_offset) return commit_graph_error("wrong commit-graph size"); memcpy(file->checksum, (data + trailer_offset), checksum_size); - if (git_hash_buf(checksum, data, (size_t)trailer_offset, GIT_HASH_ALGORITHM_SHA1) < 0) - return commit_graph_error("could not calculate signature"); - if (memcmp(checksum, file->checksum, checksum_size) != 0) - return commit_graph_error("index signature mismatch"); - chunk_hdr = data + sizeof(struct git_commit_graph_header); last_chunk = NULL; for (i = 0; i < hdr->chunks; ++i, chunk_hdr += 12) { - chunk_offset = ((off64_t)ntohl(*((uint32_t *)(chunk_hdr + 4)))) << 32 - | ((off64_t)ntohl(*((uint32_t *)(chunk_hdr + 8)))); + chunk_offset = ((uint64_t)ntohl(*((uint32_t *)(chunk_hdr + 4)))) << 32 + | ((uint64_t)ntohl(*((uint32_t *)(chunk_hdr + 8)))); if (chunk_offset < last_chunk_offset) return commit_graph_error("chunks are non-monotonic"); if (chunk_offset >= trailer_offset) @@ -331,9 +325,29 @@ error: return error; } +int git_commit_graph_validate(git_commit_graph *cgraph) { + unsigned char checksum[GIT_HASH_SHA1_SIZE]; + size_t checksum_size = GIT_HASH_SHA1_SIZE; + size_t trailer_offset = cgraph->file->graph_map.len - checksum_size; + + if (cgraph->file->graph_map.len < checksum_size) + return commit_graph_error("map length too small"); + + if (git_hash_buf(checksum, cgraph->file->graph_map.data, trailer_offset, GIT_HASH_ALGORITHM_SHA1) < 0) + return commit_graph_error("could not calculate signature"); + if (memcmp(checksum, cgraph->file->checksum, checksum_size) != 0) + return commit_graph_error("index signature mismatch"); + + return 0; +} + int git_commit_graph_open(git_commit_graph **cgraph_out, const char *objects_dir) { - return git_commit_graph_new(cgraph_out, objects_dir, true); + int error = git_commit_graph_new(cgraph_out, objects_dir, true); + if (!error) { + return git_commit_graph_validate(*cgraph_out); + } + return error; } int git_commit_graph_file_open(git_commit_graph_file **file_out, const char *path) @@ -436,15 +450,15 @@ static int git_commit_graph_entry_get_byindex( return GIT_ENOTFOUND; } - commit_data = file->commit_data + pos * (GIT_OID_RAWSZ + 4 * sizeof(uint32_t)); - git_oid_fromraw(&e->tree_oid, commit_data); - e->parent_indices[0] = ntohl(*((uint32_t *)(commit_data + GIT_OID_RAWSZ))); + commit_data = file->commit_data + pos * (GIT_OID_SHA1_SIZE + 4 * sizeof(uint32_t)); + git_oid__fromraw(&e->tree_oid, commit_data, GIT_OID_SHA1); + e->parent_indices[0] = ntohl(*((uint32_t *)(commit_data + GIT_OID_SHA1_SIZE))); e->parent_indices[1] = ntohl( - *((uint32_t *)(commit_data + GIT_OID_RAWSZ + sizeof(uint32_t)))); + *((uint32_t *)(commit_data + GIT_OID_SHA1_SIZE + sizeof(uint32_t)))); e->parent_count = (e->parent_indices[0] != GIT_COMMIT_GRAPH_MISSING_PARENT) + (e->parent_indices[1] != GIT_COMMIT_GRAPH_MISSING_PARENT); - e->generation = ntohl(*((uint32_t *)(commit_data + GIT_OID_RAWSZ + 2 * sizeof(uint32_t)))); - e->commit_time = ntohl(*((uint32_t *)(commit_data + GIT_OID_RAWSZ + 3 * sizeof(uint32_t)))); + e->generation = ntohl(*((uint32_t *)(commit_data + GIT_OID_SHA1_SIZE + 2 * sizeof(uint32_t)))); + e->commit_time = ntohl(*((uint32_t *)(commit_data + GIT_OID_SHA1_SIZE + 3 * sizeof(uint32_t)))); e->commit_time |= (e->generation & UINT64_C(0x3)) << UINT64_C(32); e->generation >>= 2u; @@ -471,7 +485,7 @@ static int git_commit_graph_entry_get_byindex( } } - git_oid_fromraw(&e->sha1, &file->oid_lookup[pos * GIT_OID_RAWSZ]); + git_oid__fromraw(&e->sha1, &file->oid_lookup[pos * GIT_OID_SHA1_SIZE], GIT_OID_SHA1); return 0; } @@ -524,27 +538,27 @@ int git_commit_graph_entry_find( hi = ntohl(file->oid_fanout[(int)short_oid->id[0]]); lo = ((short_oid->id[0] == 0x0) ? 0 : ntohl(file->oid_fanout[(int)short_oid->id[0] - 1])); - pos = git_pack__lookup_sha1(file->oid_lookup, GIT_OID_RAWSZ, lo, hi, short_oid->id); + pos = git_pack__lookup_id(file->oid_lookup, GIT_OID_SHA1_SIZE, lo, hi, short_oid->id, GIT_OID_SHA1); if (pos >= 0) { /* An object matching exactly the oid was found */ found = 1; - current = file->oid_lookup + (pos * GIT_OID_RAWSZ); + current = file->oid_lookup + (pos * GIT_OID_SHA1_SIZE); } else { /* No object was found */ /* pos refers to the object with the "closest" oid to short_oid */ pos = -1 - pos; if (pos < (int)file->num_commits) { - current = file->oid_lookup + (pos * GIT_OID_RAWSZ); + current = file->oid_lookup + (pos * GIT_OID_SHA1_SIZE); if (!git_oid_raw_ncmp(short_oid->id, current, len)) found = 1; } } - if (found && len != GIT_OID_HEXSZ && pos + 1 < (int)file->num_commits) { + if (found && len != GIT_OID_SHA1_HEXSIZE && pos + 1 < (int)file->num_commits) { /* Check for ambiguousity */ - const unsigned char *next = current + GIT_OID_RAWSZ; + const unsigned char *next = current + GIT_OID_SHA1_SIZE; if (!git_oid_raw_ncmp(short_oid->id, next, len)) found = 2; @@ -712,7 +726,8 @@ int git_commit_graph_writer_add_index_file( if (error < 0) goto cleanup; - error = git_mwindow_get_pack(&p, idx_path); + /* TODO: SHA256 */ + error = git_mwindow_get_pack(&p, idx_path, 0); if (error < 0) goto cleanup; @@ -1020,7 +1035,7 @@ static int commit_graph_write( git_vector_foreach (&w->commits, i, packed_commit) { error = git_str_put(&oid_lookup, (const char *)&packed_commit->sha1.id, - GIT_OID_RAWSZ); + GIT_OID_SHA1_SIZE); if (error < 0) goto cleanup; @@ -1037,7 +1052,7 @@ static int commit_graph_write( error = git_str_put(&commit_data, (const char *)&packed_commit->tree_oid.id, - GIT_OID_RAWSZ); + GIT_OID_SHA1_SIZE); if (error < 0) goto cleanup; diff --git a/src/libgit2/commit_graph.h b/src/libgit2/commit_graph.h index b78ab8177..517abb239 100644 --- a/src/libgit2/commit_graph.h +++ b/src/libgit2/commit_graph.h @@ -106,6 +106,9 @@ struct git_commit_graph { /** Create a new commit-graph, optionally opening the underlying file. */ int git_commit_graph_new(git_commit_graph **cgraph_out, const char *objects_dir, bool open_file); +/** Validate the checksum of a commit graph */ +int git_commit_graph_validate(git_commit_graph *cgraph); + /** Open and validate a commit-graph file. */ int git_commit_graph_file_open(git_commit_graph_file **file_out, const char *path); diff --git a/src/libgit2/commit_list.c b/src/libgit2/commit_list.c index 4585508bc..12b329b25 100644 --- a/src/libgit2/commit_list.c +++ b/src/libgit2/commit_list.c @@ -124,13 +124,17 @@ static int commit_quick_parse( { git_oid *parent_oid; git_commit *commit; + git_commit__parse_options parse_opts = { + GIT_OID_SHA1, + GIT_COMMIT_PARSE_QUICK + }; size_t i; commit = git__calloc(1, sizeof(*commit)); GIT_ERROR_CHECK_ALLOC(commit); commit->object.repo = walk->repo; - if (git_commit__parse_ext(commit, obj, GIT_COMMIT_PARSE_QUICK) < 0) { + if (git_commit__parse_ext(commit, obj, &parse_opts) < 0) { git__free(commit); return -1; } @@ -172,7 +176,7 @@ int git_commit_list_parse(git_revwalk *walk, git_commit_list_node *commit) if (cgraph_file) { git_commit_graph_entry e; - error = git_commit_graph_entry_find(&e, cgraph_file, &commit->oid, GIT_OID_RAWSZ); + error = git_commit_graph_entry_find(&e, cgraph_file, &commit->oid, GIT_OID_SHA1_SIZE); if (error == 0 && git__is_uint16(e.parent_count)) { size_t i; commit->generation = (uint32_t)e.generation; diff --git a/src/libgit2/config.c b/src/libgit2/config.c index 5c366e221..23a8f9ffa 100644 --- a/src/libgit2/config.c +++ b/src/libgit2/config.c @@ -860,7 +860,7 @@ static int git_config__parse_path(git_str *out, const char *value) return -1; } - return git_sysdir_expand_global_file(out, value[1] ? &value[2] : NULL); + return git_sysdir_expand_homedir_file(out, value[1] ? &value[2] : NULL); } return git_str_sets(out, value); @@ -1174,9 +1174,12 @@ int git_config__find_programdata(git_str *path) GIT_FS_PATH_OWNER_CURRENT_USER | GIT_FS_PATH_OWNER_ADMINISTRATOR; bool is_safe; + int error; - if (git_sysdir_find_programdata_file(path, GIT_CONFIG_FILENAME_PROGRAMDATA) < 0 || - git_fs_path_owner_is(&is_safe, path->ptr, owner_level) < 0) + if ((error = git_sysdir_find_programdata_file(path, GIT_CONFIG_FILENAME_PROGRAMDATA)) < 0) + return error; + + if (git_fs_path_owner_is(&is_safe, path->ptr, owner_level) < 0) return -1; if (!is_safe) { diff --git a/src/libgit2/config_file.c b/src/libgit2/config_file.c index 66fcb8ae2..932ca7601 100644 --- a/src/libgit2/config_file.c +++ b/src/libgit2/config_file.c @@ -528,7 +528,7 @@ static int included_path(git_str *out, const char *dir, const char *path) { /* From the user's home */ if (path[0] == '~' && path[1] == '/') - return git_sysdir_expand_global_file(out, &path[1]); + return git_sysdir_expand_homedir_file(out, &path[1]); return git_fs_path_join_unrooted(out, path, dir, NULL); } @@ -616,7 +616,7 @@ static int do_match_gitdir( git_fs_path_dirname_r(&pattern, cfg_file); git_str_joinpath(&pattern, pattern.ptr, condition + 2); } else if (condition[0] == '~' && git_fs_path_is_dirsep(condition[1])) - git_sysdir_expand_global_file(&pattern, condition + 1); + git_sysdir_expand_homedir_file(&pattern, condition + 1); else if (!git_fs_path_is_absolute(condition)) git_str_joinpath(&pattern, "**", condition); else diff --git a/src/libgit2/describe.c b/src/libgit2/describe.c index 1033eac50..3f73d87d6 100644 --- a/src/libgit2/describe.c +++ b/src/libgit2/describe.c @@ -8,7 +8,6 @@ #include "common.h" #include "git2/describe.h" -#include "git2/strarray.h" #include "git2/diff.h" #include "git2/status.h" @@ -19,6 +18,7 @@ #include "refs.h" #include "repository.h" #include "revwalk.h" +#include "strarray.h" #include "tag.h" #include "vector.h" #include "wildmatch.h" @@ -368,7 +368,7 @@ static int find_unique_abbrev_size( if ((error = git_repository_odb__weakptr(&odb, repo)) < 0) return error; - while (size < GIT_OID_HEXSZ) { + while (size < GIT_OID_SHA1_HEXSIZE) { if ((error = git_odb_exists_prefix(&dummy, odb, oid_in, size)) == 0) { *out = (int) size; return 0; @@ -383,7 +383,7 @@ static int find_unique_abbrev_size( } /* If we didn't find any shorter prefix, we have to do the whole thing */ - *out = GIT_OID_HEXSZ; + *out = GIT_OID_SHA1_HEXSIZE; return 0; } @@ -397,7 +397,7 @@ static int show_suffix( { int error, size = 0; - char hex_oid[GIT_OID_HEXSZ]; + char hex_oid[GIT_OID_SHA1_HEXSIZE]; if ((error = find_unique_abbrev_size(&size, repo, id, abbrev_size)) < 0) return error; @@ -414,7 +414,7 @@ static int show_suffix( #define MAX_CANDIDATES_TAGS FLAG_BITS - 1 static int describe_not_found(const git_oid *oid, const char *message_format) { - char oid_str[GIT_OID_HEXSZ + 1]; + char oid_str[GIT_OID_SHA1_HEXSIZE + 1]; git_oid_tostr(oid_str, sizeof(oid_str), oid); git_error_set(GIT_ERROR_DESCRIBE, message_format, oid_str); @@ -525,7 +525,7 @@ static int describe( if (annotated_cnt && (git_pqueue_size(&list) == 0)) { /* if (debug) { - char oid_str[GIT_OID_HEXSZ + 1]; + char oid_str[GIT_OID_SHA1_HEXSIZE + 1]; git_oid_tostr(oid_str, sizeof(oid_str), &c->oid); fprintf(stderr, "finished search at %s\n", oid_str); @@ -592,7 +592,7 @@ static int describe( "head", "lightweight", "annotated", }; - char oid_str[GIT_OID_HEXSZ + 1]; + char oid_str[GIT_OID_SHA1_HEXSIZE + 1]; if (debug) { for (cur_match = 0; cur_match < match_cnt; cur_match++) { @@ -816,7 +816,7 @@ static int git_describe__format( /* If we didn't find *any* tags, we fall back to the commit's id */ if (result->fallback_to_id) { - char hex_oid[GIT_OID_HEXSZ + 1] = {0}; + char hex_oid[GIT_OID_SHA1_HEXSIZE + 1] = {0}; int size = 0; if ((error = find_unique_abbrev_size( diff --git a/src/libgit2/diff.c b/src/libgit2/diff.c index 9840d6050..20a18c4b9 100644 --- a/src/libgit2/diff.c +++ b/src/libgit2/diff.c @@ -290,7 +290,7 @@ static int flush_hunk(git_oid *result, git_hash_ctx *ctx) (error = git_hash_init(ctx)) < 0) return error; - for (i = 0; i < GIT_OID_RAWSZ; i++) { + for (i = 0; i < GIT_OID_SHA1_SIZE; i++) { carry += result->id[i] + hash.id[i]; result->id[i] = (unsigned char)carry; carry >>= 8; @@ -381,6 +381,10 @@ int git_diff_patchid(git_oid *out, git_diff *diff, git_diff_patchid_options *opt if ((error = (flush_hunk(&args.result, &args.ctx))) < 0) goto out; +#ifdef GIT_EXPERIMENTAL_SHA256 + args.result.type = GIT_OID_SHA1; +#endif + git_oid_cpy(out, &args.result); out: diff --git a/src/libgit2/diff_file.c b/src/libgit2/diff_file.c index c7e9fbeee..c2d08675a 100644 --- a/src/libgit2/diff_file.c +++ b/src/libgit2/diff_file.c @@ -144,6 +144,7 @@ int git_diff_file_content__init_from_src( if (!src->blob && !src->buf) { fc->flags |= GIT_DIFF_FLAG__NO_DATA; + git_oid_clear(&fc->file->id, GIT_OID_SHA1); } else { fc->flags |= GIT_DIFF_FLAG__LOADED; fc->file->flags |= GIT_DIFF_FLAG_VALID_ID; @@ -153,7 +154,7 @@ int git_diff_file_content__init_from_src( git_blob_dup((git_blob **)&fc->blob, (git_blob *) src->blob); fc->file->size = git_blob_rawsize(src->blob); git_oid_cpy(&fc->file->id, git_blob_id(src->blob)); - fc->file->id_abbrev = GIT_OID_HEXSZ; + fc->file->id_abbrev = GIT_OID_SHA1_HEXSIZE; fc->map.len = (size_t)fc->file->size; fc->map.data = (char *)git_blob_rawcontent(src->blob); @@ -161,10 +162,10 @@ int git_diff_file_content__init_from_src( fc->flags |= GIT_DIFF_FLAG__FREE_BLOB; } else { int error; - if ((error = git_odb_hash(&fc->file->id, src->buf, src->buflen, GIT_OBJECT_BLOB)) < 0) + if ((error = git_odb__hash(&fc->file->id, src->buf, src->buflen, GIT_OBJECT_BLOB, GIT_OID_SHA1)) < 0) return error; fc->file->size = src->buflen; - fc->file->id_abbrev = GIT_OID_HEXSZ; + fc->file->id_abbrev = GIT_OID_SHA1_HEXSIZE; fc->map.len = src->buflen; fc->map.data = (char *)src->buf; @@ -177,7 +178,7 @@ int git_diff_file_content__init_from_src( static int diff_file_content_commit_to_str( git_diff_file_content *fc, bool check_status) { - char oid[GIT_OID_HEXSZ+1]; + char oid[GIT_OID_SHA1_HEXSIZE+1]; git_str content = GIT_STR_INIT; const char *status = ""; @@ -347,6 +348,13 @@ static int diff_file_content_load_workdir_file( goto cleanup; } + /* if file is empty, don't attempt to mmap or readbuffer */ + if (fc->file->size == 0) { + fc->map.len = 0; + fc->map.data = git_str__initstr; + goto cleanup; + } + if ((diff_opts->flags & GIT_DIFF_SHOW_BINARY) == 0 && diff_file_content_binary_by_size(fc)) goto cleanup; @@ -410,8 +418,9 @@ static int diff_file_content_load_workdir( /* once data is loaded, update OID if we didn't have it previously */ if (!error && (fc->file->flags & GIT_DIFF_FLAG_VALID_ID) == 0) { - error = git_odb_hash( - &fc->file->id, fc->map.data, fc->map.len, GIT_OBJECT_BLOB); + error = git_odb__hash( + &fc->file->id, fc->map.data, fc->map.len, + GIT_OBJECT_BLOB, GIT_OID_SHA1); fc->file->flags |= GIT_DIFF_FLAG_VALID_ID; } diff --git a/src/libgit2/diff_generate.c b/src/libgit2/diff_generate.c index cfaefba66..a88ce8c32 100644 --- a/src/libgit2/diff_generate.c +++ b/src/libgit2/diff_generate.c @@ -61,6 +61,9 @@ static git_diff_delta *diff_delta__alloc( } delta->status = status; + git_oid_clear(&delta->old_file.id, GIT_OID_SHA1); + git_oid_clear(&delta->new_file.id, GIT_OID_SHA1); + return delta; } @@ -188,13 +191,15 @@ static int diff_delta__from_one( delta->old_file.size = entry->file_size; delta->old_file.flags |= GIT_DIFF_FLAG_EXISTS; git_oid_cpy(&delta->old_file.id, &entry->id); - delta->old_file.id_abbrev = GIT_OID_HEXSZ; + git_oid_clear(&delta->new_file.id, GIT_OID_SHA1); + delta->old_file.id_abbrev = GIT_OID_SHA1_HEXSIZE; } else /* ADDED, IGNORED, UNTRACKED */ { delta->new_file.mode = entry->mode; delta->new_file.size = entry->file_size; delta->new_file.flags |= GIT_DIFF_FLAG_EXISTS; + git_oid_clear(&delta->old_file.id, GIT_OID_SHA1); git_oid_cpy(&delta->new_file.id, &entry->id); - delta->new_file.id_abbrev = GIT_OID_HEXSZ; + delta->new_file.id_abbrev = GIT_OID_SHA1_HEXSIZE; } delta->old_file.flags |= GIT_DIFF_FLAG_VALID_ID; @@ -249,14 +254,14 @@ static int diff_delta__from_two( delta->old_file.size = old_entry->file_size; delta->old_file.mode = old_mode; git_oid_cpy(&delta->old_file.id, old_id); - delta->old_file.id_abbrev = GIT_OID_HEXSZ; + delta->old_file.id_abbrev = GIT_OID_SHA1_HEXSIZE; delta->old_file.flags |= GIT_DIFF_FLAG_VALID_ID | GIT_DIFF_FLAG_EXISTS; } if (!git_index_entry_is_conflict(new_entry)) { git_oid_cpy(&delta->new_file.id, new_id); - delta->new_file.id_abbrev = GIT_OID_HEXSZ; + delta->new_file.id_abbrev = GIT_OID_SHA1_HEXSIZE; delta->new_file.size = new_entry->file_size; delta->new_file.mode = new_mode; delta->old_file.flags |= GIT_DIFF_FLAG_EXISTS; @@ -598,6 +603,7 @@ int git_diff__oid_for_file( entry.mode = mode; entry.file_size = (uint32_t)size; entry.path = (char *)path; + git_oid_clear(&entry.id, GIT_OID_SHA1); return git_diff__oid_for_entry(out, diff, &entry, mode, NULL); } @@ -618,7 +624,7 @@ int git_diff__oid_for_entry( GIT_ASSERT(d->type == GIT_DIFF_TYPE_GENERATED); diff = (git_diff_generated *)d; - memset(out, 0, sizeof(*out)); + git_oid_clear(out, GIT_OID_SHA1); if (git_repository_workdir_path(&full_path, diff->base.repo, entry.path) < 0) return -1; @@ -654,7 +660,7 @@ int git_diff__oid_for_entry( git_error_clear(); } } else if (S_ISLNK(mode)) { - error = git_odb__hashlink(out, full_path.ptr); + error = git_odb__hashlink(out, full_path.ptr, GIT_OID_SHA1); diff->base.perf.oid_calculations++; } else if (!git__is_sizet(entry.file_size)) { git_error_set(GIT_ERROR_NOMEMORY, "file size overflow (for 32-bits) on '%s'", @@ -669,7 +675,8 @@ int git_diff__oid_for_entry( error = fd; else { error = git_odb__hashfd_filtered( - out, fd, (size_t)entry.file_size, GIT_OBJECT_BLOB, fl); + out, fd, (size_t)entry.file_size, + GIT_OBJECT_BLOB, GIT_OID_SHA1, fl); p_close(fd); diff->base.perf.oid_calculations++; } @@ -778,7 +785,7 @@ static int maybe_modified( git_diff_generated *diff, diff_in_progress *info) { - git_oid noid; + git_oid noid = GIT_OID_SHA1_ZERO; git_delta_t status = GIT_DELTA_MODIFIED; const git_index_entry *oitem = info->oitem; const git_index_entry *nitem = info->nitem; @@ -792,8 +799,6 @@ static int maybe_modified( if (!diff_pathspec_match(&matched_pathspec, diff, oitem)) return 0; - memset(&noid, 0, sizeof(noid)); - /* on platforms with no symlinks, preserve mode of existing symlinks */ if (S_ISLNK(omode) && S_ISREG(nmode) && new_is_workdir && !(diff->diffcaps & GIT_DIFFCAPS_HAS_SYMLINKS)) @@ -1695,11 +1700,11 @@ int git_diff__commit( *out = NULL; if ((parents = git_commit_parentcount(commit)) > 1) { - char commit_oidstr[GIT_OID_HEXSZ + 1]; + char commit_oidstr[GIT_OID_SHA1_HEXSIZE + 1]; error = -1; git_error_set(GIT_ERROR_INVALID, "commit %s is a merge commit", - git_oid_tostr(commit_oidstr, GIT_OID_HEXSZ + 1, git_commit_id(commit))); + git_oid_tostr(commit_oidstr, GIT_OID_SHA1_HEXSIZE + 1, git_commit_id(commit))); goto on_error; } diff --git a/src/libgit2/diff_print.c b/src/libgit2/diff_print.c index 6c5a2cdc8..3077e11e1 100644 --- a/src/libgit2/diff_print.c +++ b/src/libgit2/diff_print.c @@ -53,8 +53,8 @@ static int diff_print_info_init__common( return -1; } - if (pi->id_strlen > GIT_OID_HEXSZ) - pi->id_strlen = GIT_OID_HEXSZ; + if (pi->id_strlen > GIT_OID_SHA1_HEXSIZE) + pi->id_strlen = GIT_OID_SHA1_HEXSIZE; memset(&pi->line, 0, sizeof(pi->line)); pi->line.old_lineno = -1; @@ -212,7 +212,7 @@ static int diff_print_one_raw( git_str *out = pi->buf; int id_abbrev; char code = git_diff_status_char(delta->status); - char start_oid[GIT_OID_HEXSZ+1], end_oid[GIT_OID_HEXSZ+1]; + char start_oid[GIT_OID_SHA1_HEXSIZE+1], end_oid[GIT_OID_SHA1_HEXSIZE+1]; GIT_UNUSED(progress); @@ -235,7 +235,7 @@ static int diff_print_one_raw( git_oid_tostr(end_oid, pi->id_strlen + 1, &delta->new_file.id); git_str_printf( - out, (pi->id_strlen <= GIT_OID_HEXSZ) ? + out, (pi->id_strlen <= GIT_OID_SHA1_HEXSIZE) ? ":%06o %06o %s... %s... %c" : ":%06o %06o %s %s %c", delta->old_file.mode, delta->new_file.mode, start_oid, end_oid, code); @@ -273,7 +273,7 @@ static int diff_print_oid_range( git_str *out, const git_diff_delta *delta, int id_strlen, bool print_index) { - char start_oid[GIT_OID_HEXSZ+1], end_oid[GIT_OID_HEXSZ+1]; + char start_oid[GIT_OID_SHA1_HEXSIZE+1], end_oid[GIT_OID_SHA1_HEXSIZE+1]; if (delta->old_file.mode && id_strlen > delta->old_file.id_abbrev) { diff --git a/src/libgit2/diff_tform.c b/src/libgit2/diff_tform.c index 913d649b0..8c0c1b7fc 100644 --- a/src/libgit2/diff_tform.c +++ b/src/libgit2/diff_tform.c @@ -364,6 +364,7 @@ static int insert_delete_side_of_split( memset(&deleted->new_file, 0, sizeof(deleted->new_file)); deleted->new_file.path = deleted->old_file.path; deleted->new_file.flags |= GIT_DIFF_FLAG_VALID_ID; + git_oid_clear(&deleted->new_file.id, GIT_OID_SHA1); return git_vector_insert(onto, deleted); } @@ -397,6 +398,7 @@ static int apply_splits_and_deletes( memset(&delta->old_file, 0, sizeof(delta->old_file)); delta->old_file.path = delta->new_file.path; delta->old_file.flags |= GIT_DIFF_FLAG_VALID_ID; + git_oid_clear(&delta->old_file.id, GIT_OID_SHA1); } /* clean up delta before inserting into new list */ @@ -995,6 +997,7 @@ find_best_matches: memset(&src->new_file, 0, sizeof(src->new_file)); src->new_file.path = src->old_file.path; src->new_file.flags |= GIT_DIFF_FLAG_VALID_ID; + git_oid_clear(&src->new_file.id, GIT_OID_SHA1); num_updates++; @@ -1020,6 +1023,7 @@ find_best_matches: memset(&src->old_file, 0, sizeof(src->old_file)); src->old_file.path = src->new_file.path; src->old_file.flags |= GIT_DIFF_FLAG_VALID_ID; + git_oid_clear(&src->old_file.id, GIT_OID_SHA1); src->flags &= ~GIT_DIFF_FLAG__TO_SPLIT; num_rewrites--; diff --git a/src/libgit2/email.c b/src/libgit2/email.c index e19a2928c..0a75021c8 100644 --- a/src/libgit2/email.c +++ b/src/libgit2/email.c @@ -130,11 +130,11 @@ static int append_header( const git_signature *author, git_email_create_options *opts) { - char id[GIT_OID_HEXSZ]; + char id[GIT_OID_SHA1_HEXSIZE]; int error; if ((error = git_oid_fmt(id, commit_id)) < 0 || - (error = git_str_printf(out, "From %.*s %s\n", GIT_OID_HEXSZ, id, EMAIL_TIMESTAMP)) < 0 || + (error = git_str_printf(out, "From %.*s %s\n", GIT_OID_SHA1_HEXSIZE, id, EMAIL_TIMESTAMP)) < 0 || (error = git_str_printf(out, "From: %s <%s>\n", author->name, author->email)) < 0 || (error = append_date(out, &author->when)) < 0 || (error = append_subject(out, patch_idx, patch_count, summary, opts)) < 0) diff --git a/src/libgit2/experimental.h.in b/src/libgit2/experimental.h.in new file mode 100644 index 000000000..25fb14b9d --- /dev/null +++ b/src/libgit2/experimental.h.in @@ -0,0 +1,13 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ + +#ifndef INCLUDE_experimental_h__ +#define INCLUDE_experimental_h__ + +#cmakedefine GIT_EXPERIMENTAL_SHA256 1 + +#endif diff --git a/src/libgit2/fetch.c b/src/libgit2/fetch.c index e9f30d9bc..003b5198a 100644 --- a/src/libgit2/fetch.c +++ b/src/libgit2/fetch.c @@ -13,6 +13,7 @@ #include "git2/transport.h" #include "git2/sys/remote.h" +#include "oid.h" #include "remote.h" #include "refspec.h" #include "pack.h" @@ -75,7 +76,7 @@ static int maybe_want_oid(git_remote *remote, git_refspec *spec) oid_head = git__calloc(1, sizeof(git_remote_head)); GIT_ERROR_CHECK_ALLOC(oid_head); - git_oid_fromstr(&oid_head->oid, spec->src); + git_oid__fromstr(&oid_head->oid, spec->src, GIT_OID_SHA1); if (spec->dst) { oid_head->name = git__strdup(spec->dst); @@ -94,7 +95,6 @@ static int filter_wants(git_remote *remote, const git_fetch_options *opts) git_remote_head **heads; git_refspec tagspec, head, *spec; int error = 0; - git_odb *odb; size_t i, heads_len; unsigned int remote_caps; unsigned int oid_mask = GIT_REMOTE_CAPABILITY_TIP_OID | @@ -125,9 +125,6 @@ static int filter_wants(git_remote *remote, const git_fetch_options *opts) goto cleanup; } - if ((error = git_repository_odb__weakptr(&odb, remote->repo)) < 0) - goto cleanup; - if ((error = git_remote_ls((const git_remote_head ***)&heads, &heads_len, remote)) < 0 || (error = git_remote_capabilities(&remote_caps, remote)) < 0) goto cleanup; @@ -140,7 +137,7 @@ static int filter_wants(git_remote *remote, const git_fetch_options *opts) /* Handle explicitly specified OID specs */ git_vector_foreach(&remote->active_refspecs, i, spec) { - if (!git_oid__is_hexstr(spec->src)) + if (!git_oid__is_hexstr(spec->src, GIT_OID_SHA1)) continue; if (!(remote_caps & oid_mask)) { diff --git a/src/libgit2/fetchhead.c b/src/libgit2/fetchhead.c index 6511124ef..0ebfe5c43 100644 --- a/src/libgit2/fetchhead.c +++ b/src/libgit2/fetchhead.c @@ -105,7 +105,7 @@ static int fetchhead_ref_write( git_filebuf *file, git_fetchhead_ref *fetchhead_ref) { - char oid[GIT_OID_HEXSZ + 1]; + char oid[GIT_OID_SHA1_HEXSIZE + 1]; const char *type, *name; int head = 0; @@ -113,7 +113,7 @@ static int fetchhead_ref_write( GIT_ASSERT_ARG(fetchhead_ref); git_oid_fmt(oid, &fetchhead_ref->oid); - oid[GIT_OID_HEXSZ] = '\0'; + oid[GIT_OID_SHA1_HEXSIZE] = '\0'; if (git__prefixcmp(fetchhead_ref->ref_name, GIT_REFS_HEADS_DIR) == 0) { type = "branch "; @@ -196,13 +196,13 @@ static int fetchhead_ref_parse( *is_merge = 1; } - if (strlen(oid_str) != GIT_OID_HEXSZ) { + if (strlen(oid_str) != GIT_OID_SHA1_HEXSIZE) { git_error_set(GIT_ERROR_FETCHHEAD, "invalid object ID in FETCH_HEAD line %"PRIuZ, line_num); return -1; } - if (git_oid_fromstr(oid, oid_str) < 0) { + if (git_oid__fromstr(oid, oid_str, GIT_OID_SHA1) < 0) { const git_error *oid_err = git_error_last(); const char *err_msg = oid_err ? oid_err->message : "invalid object ID"; diff --git a/src/libgit2/ident.c b/src/libgit2/ident.c index 53095864e..bf9a4998e 100644 --- a/src/libgit2/ident.c +++ b/src/libgit2/ident.c @@ -42,7 +42,7 @@ static int ident_find_id( static int ident_insert_id( git_str *to, const git_str *from, const git_filter_source *src) { - char oid[GIT_OID_HEXSZ+1]; + char oid[GIT_OID_SHA1_HEXSIZE+1]; const char *id_start, *id_end, *from_end = from->ptr + from->size; size_t need_size; @@ -57,7 +57,7 @@ static int ident_insert_id( return GIT_PASSTHROUGH; need_size = (size_t)(id_start - from->ptr) + - 5 /* "$Id: " */ + GIT_OID_HEXSZ + 2 /* " $" */ + + 5 /* "$Id: " */ + GIT_OID_SHA1_HEXSIZE + 2 /* " $" */ + (size_t)(from_end - id_end); if (git_str_grow(to, need_size) < 0) @@ -65,7 +65,7 @@ static int ident_insert_id( git_str_set(to, from->ptr, (size_t)(id_start - from->ptr)); git_str_put(to, "$Id: ", 5); - git_str_put(to, oid, GIT_OID_HEXSZ); + git_str_put(to, oid, GIT_OID_SHA1_HEXSIZE); git_str_put(to, " $", 2); git_str_put(to, id_end, (size_t)(from_end - id_end)); diff --git a/src/libgit2/index.c b/src/libgit2/index.c index f44c507d3..d4532c005 100644 --- a/src/libgit2/index.c +++ b/src/libgit2/index.c @@ -74,7 +74,7 @@ struct entry_short { uint32_t uid; uint32_t gid; uint32_t file_size; - unsigned char oid[GIT_OID_RAWSZ]; + unsigned char oid[GIT_OID_SHA1_SIZE]; uint16_t flags; char path[1]; /* arbitrary length */ }; @@ -88,7 +88,7 @@ struct entry_long { uint32_t uid; uint32_t gid; uint32_t file_size; - unsigned char oid[GIT_OID_RAWSZ]; + unsigned char oid[GIT_OID_SHA1_SIZE]; uint16_t flags; uint16_t flags_extended; char path[1]; /* arbitrary length */ @@ -2354,14 +2354,16 @@ static int read_reuc(git_index *index, const char *buffer, size_t size) for (i = 0; i < 3; i++) { if (!lost->mode[i]) continue; - if (size < 20) { + if (size < GIT_OID_SHA1_SIZE) { index_entry_reuc_free(lost); return index_error_invalid("reading reuc entry oid"); } - git_oid_fromraw(&lost->oid[i], (const unsigned char *) buffer); - size -= 20; - buffer += 20; + if (git_oid__fromraw(&lost->oid[i], (const unsigned char *) buffer, GIT_OID_SHA1) < 0) + return -1; + + size -= GIT_OID_SHA1_SIZE; + buffer += GIT_OID_SHA1_SIZE; } /* entry was read successfully - insert into reuc vector */ @@ -2482,7 +2484,7 @@ static int read_entry( entry.file_size = ntohl(source.file_size); entry.flags = ntohs(source.flags); - if (git_oid_fromraw(&entry.id, source.oid) < 0) + if (git_oid__fromraw(&entry.id, source.oid, GIT_OID_SHA1) < 0) return -1; if (entry.flags & GIT_INDEX_ENTRY_EXTENDED) { @@ -2805,7 +2807,7 @@ static int write_disk_entry(git_filebuf *file, git_index_entry *entry, const cha ondisk.uid = htonl(entry->uid); ondisk.gid = htonl(entry->gid); ondisk.file_size = htonl((uint32_t)entry->file_size); - git_oid_raw_cpy(ondisk.oid, entry->id.id); + git_oid_raw_cpy(ondisk.oid, entry->id.id, GIT_OID_SHA1_SIZE); ondisk.flags = htons(entry->flags); if (entry->flags & GIT_INDEX_ENTRY_EXTENDED) { @@ -2968,7 +2970,7 @@ static int create_reuc_extension_data(git_str *reuc_buf, git_index_reuc_entry *r } for (i = 0; i < 3; i++) { - if (reuc->mode[i] && (error = git_str_put(reuc_buf, (char *)&reuc->oid[i].id, GIT_OID_RAWSZ)) < 0) + if (reuc->mode[i] && (error = git_str_put(reuc_buf, (char *)&reuc->oid[i].id, GIT_OID_SHA1_SIZE)) < 0) return error; } @@ -3395,7 +3397,6 @@ int git_index_add_all( { int error; git_repository *repo; - git_iterator *wditer = NULL; git_pathspec ps; bool no_fnmatch = (flags & GIT_INDEX_ADD_DISABLE_PATHSPEC_MATCH) != 0; @@ -3421,7 +3422,6 @@ int git_index_add_all( git_error_set_after_callback(error); cleanup: - git_iterator_free(wditer); git_pathspec__clear(&ps); return error; @@ -3509,7 +3509,8 @@ static int index_apply_to_wd_diff(git_index *index, int action, const git_strarr GIT_DIFF_RECURSE_UNTRACKED_DIRS; if (flags == GIT_INDEX_ADD_FORCE) - opts.flags |= GIT_DIFF_INCLUDE_IGNORED; + opts.flags |= GIT_DIFF_INCLUDE_IGNORED | + GIT_DIFF_RECURSE_IGNORED_DIRS; } if ((error = git_diff_index_to_workdir(&diff, repo, index, &opts)) < 0) diff --git a/src/libgit2/indexer.c b/src/libgit2/indexer.c index afb9ce81a..fa55fb5ea 100644 --- a/src/libgit2/indexer.c +++ b/src/libgit2/indexer.c @@ -42,6 +42,7 @@ struct git_indexer { have_delta :1, do_fsync :1, do_verify :1; + git_oid_t oid_type; struct git_pack_header hdr; struct git_pack_file *pack; unsigned int mode; @@ -55,8 +56,8 @@ struct git_indexer { git_vector deltas; unsigned int fanout[256]; git_hash_ctx hash_ctx; - unsigned char checksum[GIT_HASH_SHA1_SIZE]; - char name[(GIT_HASH_SHA1_SIZE * 2) + 1]; + unsigned char checksum[GIT_HASH_MAX_SIZE]; + char name[(GIT_HASH_MAX_SIZE * 2) + 1]; git_indexer_progress_cb progress_cb; void *progress_payload; char objbuf[8*1024]; @@ -68,7 +69,7 @@ struct git_indexer { git_odb *odb; /* Fields for calculating the packfile trailer (hash of everything before it) */ - char inbuf[GIT_OID_RAWSZ]; + char inbuf[GIT_HASH_MAX_SIZE]; size_t inbuf_len; git_hash_ctx trailer; }; @@ -136,17 +137,33 @@ int git_indexer_init_options(git_indexer_options *opts, unsigned int version) } #endif -int git_indexer_new( - git_indexer **out, - const char *prefix, - unsigned int mode, - git_odb *odb, - git_indexer_options *in_opts) +GIT_INLINE(git_hash_algorithm_t) indexer_hash_algorithm(git_indexer *idx) +{ + switch (idx->oid_type) { + case GIT_OID_SHA1: + return GIT_HASH_ALGORITHM_SHA1; +#ifdef GIT_EXPERIMENTAL_SHA256 + case GIT_OID_SHA256: + return GIT_HASH_ALGORITHM_SHA256; +#endif + } + + return GIT_HASH_ALGORITHM_NONE; +} + +static int indexer_new( + git_indexer **out, + const char *prefix, + git_oid_t oid_type, + unsigned int mode, + git_odb *odb, + git_indexer_options *in_opts) { git_indexer_options opts = GIT_INDEXER_OPTIONS_INIT; git_indexer *idx; git_str path = GIT_STR_INIT, tmp_path = GIT_STR_INIT; static const char suff[] = "/pack"; + git_hash_algorithm_t checksum_type; int error, fd = -1; if (in_opts) @@ -154,14 +171,17 @@ int git_indexer_new( idx = git__calloc(1, sizeof(git_indexer)); GIT_ERROR_CHECK_ALLOC(idx); + idx->oid_type = oid_type; idx->odb = odb; idx->progress_cb = opts.progress_cb; idx->progress_payload = opts.progress_cb_payload; idx->mode = mode ? mode : GIT_PACK_FILE_MODE; git_str_init(&idx->entry_data, 0); - if ((error = git_hash_ctx_init(&idx->hash_ctx, GIT_HASH_ALGORITHM_SHA1)) < 0 || - (error = git_hash_ctx_init(&idx->trailer, GIT_HASH_ALGORITHM_SHA1)) < 0 || + checksum_type = indexer_hash_algorithm(idx); + + if ((error = git_hash_ctx_init(&idx->hash_ctx, checksum_type)) < 0 || + (error = git_hash_ctx_init(&idx->trailer, checksum_type)) < 0 || (error = git_oidmap_new(&idx->expected_oids)) < 0) goto cleanup; @@ -179,7 +199,7 @@ int git_indexer_new( if (fd < 0) goto cleanup; - error = git_packfile_alloc(&idx->pack, git_str_cstr(&tmp_path)); + error = git_packfile_alloc(&idx->pack, git_str_cstr(&tmp_path), oid_type); git_str_dispose(&tmp_path); if (error < 0) @@ -208,6 +228,33 @@ cleanup: return -1; } +#ifdef GIT_EXPERIMENTAL_SHA256 +int git_indexer_new( + git_indexer **out, + const char *prefix, + git_oid_t oid_type, + git_indexer_options *opts) +{ + return indexer_new( + out, + prefix, + oid_type, + opts ? opts->mode : 0, + opts ? opts->odb : NULL, + opts); +} +#else +int git_indexer_new( + git_indexer **out, + const char *prefix, + unsigned int mode, + git_odb *odb, + git_indexer_options *opts) +{ + return indexer_new(out, prefix, GIT_OID_SHA1, mode, odb, opts); +} +#endif + void git_indexer__set_fsync(git_indexer *idx, int do_fsync) { idx->do_fsync = !!do_fsync; @@ -272,7 +319,7 @@ static int advance_delta_offset(git_indexer *idx, git_object_t type) GIT_ASSERT_ARG(type == GIT_OBJECT_REF_DELTA || type == GIT_OBJECT_OFS_DELTA); if (type == GIT_OBJECT_REF_DELTA) { - idx->off += GIT_OID_RAWSZ; + idx->off += git_oid_size(idx->oid_type); } else { off64_t base_off; int error = get_delta_base(&base_off, idx->pack, &w, &idx->off, type, idx->entry_start); @@ -356,7 +403,7 @@ static int check_object_connectivity(git_indexer *idx, const git_rawobj *obj) obj->type != GIT_OBJECT_TAG) return 0; - if (git_object__from_raw(&object, obj->data, obj->len, obj->type) < 0) { + if (git_object__from_raw(&object, obj->data, obj->len, obj->type, idx->oid_type) < 0) { /* * parse_raw returns EINVALID on invalid data; downgrade * that to a normal -1 error code. @@ -444,6 +491,11 @@ static int store_object(git_indexer *idx) git__free(pentry); goto on_error; } + +#ifdef GIT_EXPERIMENTAL_SHA256 + oid.type = idx->oid_type; +#endif + entry_size = idx->off - entry_start; if (entry_start > UINT31_MAX) { entry->offset = UINT32_MAX; @@ -463,16 +515,16 @@ static int store_object(git_indexer *idx) goto on_error; } - git_oid_cpy(&pentry->sha1, &oid); + git_oid_cpy(&pentry->id, &oid); pentry->offset = entry_start; - if (git_oidmap_exists(idx->pack->idx_cache, &pentry->sha1)) { - git_error_set(GIT_ERROR_INDEXER, "duplicate object %s found in pack", git_oid_tostr_s(&pentry->sha1)); + if (git_oidmap_exists(idx->pack->idx_cache, &pentry->id)) { + git_error_set(GIT_ERROR_INDEXER, "duplicate object %s found in pack", git_oid_tostr_s(&pentry->id)); git__free(pentry); goto on_error; } - if ((error = git_oidmap_set(idx->pack->idx_cache, &pentry->sha1, pentry)) < 0) { + if ((error = git_oidmap_set(idx->pack->idx_cache, &pentry->id, pentry)) < 0) { git__free(pentry); git_error_set_oom(); goto on_error; @@ -517,8 +569,8 @@ static int save_entry(git_indexer *idx, struct entry *entry, struct git_pack_ent pentry->offset = entry_start; - if (git_oidmap_exists(idx->pack->idx_cache, &pentry->sha1) || - git_oidmap_set(idx->pack->idx_cache, &pentry->sha1, pentry) < 0) { + if (git_oidmap_exists(idx->pack->idx_cache, &pentry->id) || + git_oidmap_set(idx->pack->idx_cache, &pentry->id, pentry) < 0) { git_error_set(GIT_ERROR_INDEXER, "cannot insert object into pack"); return -1; } @@ -544,7 +596,7 @@ static int hash_and_save(git_indexer *idx, git_rawobj *obj, off64_t entry_start) entry = git__calloc(1, sizeof(*entry)); GIT_ERROR_CHECK_ALLOC(entry); - if (git_odb__hashobj(&oid, obj) < 0) { + if (git_odb__hashobj(&oid, obj, idx->oid_type) < 0) { git_error_set(GIT_ERROR_INDEXER, "failed to hash object"); goto on_error; } @@ -552,7 +604,7 @@ static int hash_and_save(git_indexer *idx, git_rawobj *obj, off64_t entry_start) pentry = git__calloc(1, sizeof(struct git_pack_entry)); GIT_ERROR_CHECK_ALLOC(pentry); - git_oid_cpy(&pentry->sha1, &oid); + git_oid_cpy(&pentry->id, &oid); git_oid_cpy(&entry->oid, &oid); entry->crc = crc32(0L, Z_NULL, 0); @@ -578,34 +630,38 @@ static int do_progress_callback(git_indexer *idx, git_indexer_progress *stats) return 0; } -/* Hash everything but the last 20B of input */ +/* Hash everything but the checksum trailer */ static void hash_partially(git_indexer *idx, const uint8_t *data, size_t size) { size_t to_expell, to_keep; + size_t oid_size = git_oid_size(idx->oid_type); if (size == 0) return; - /* Easy case, dump the buffer and the data minus the last 20 bytes */ - if (size >= GIT_OID_RAWSZ) { + /* + * Easy case, dump the buffer and the data minus the trailing + * checksum (SHA1 or SHA256). + */ + if (size >= oid_size) { git_hash_update(&idx->trailer, idx->inbuf, idx->inbuf_len); - git_hash_update(&idx->trailer, data, size - GIT_OID_RAWSZ); + git_hash_update(&idx->trailer, data, size - oid_size); - data += size - GIT_OID_RAWSZ; - memcpy(idx->inbuf, data, GIT_OID_RAWSZ); - idx->inbuf_len = GIT_OID_RAWSZ; + data += size - oid_size; + memcpy(idx->inbuf, data, oid_size); + idx->inbuf_len = oid_size; return; } /* We can just append */ - if (idx->inbuf_len + size <= GIT_OID_RAWSZ) { + if (idx->inbuf_len + size <= oid_size) { memcpy(idx->inbuf + idx->inbuf_len, data, size); idx->inbuf_len += size; return; } /* We need to partially drain the buffer and then append */ - to_keep = GIT_OID_RAWSZ - size; + to_keep = oid_size - size; to_expell = idx->inbuf_len - to_keep; git_hash_update(&idx->trailer, idx->inbuf, to_expell); @@ -724,12 +780,14 @@ static int read_stream_object(git_indexer *idx, git_indexer_progress *stats) { git_packfile_stream *stream = &idx->stream; off64_t entry_start = idx->off; - size_t entry_size; + size_t oid_size, entry_size; git_object_t type; git_mwindow *w = NULL; int error; - if (idx->pack->mwf.size <= idx->off + 20) + oid_size = git_oid_size(idx->oid_type); + + if (idx->pack->mwf.size <= idx->off + (long long)oid_size) return GIT_EBUFS; if (!idx->have_stream) { @@ -900,7 +958,7 @@ static int index_path(git_str *path, git_indexer *idx, const char *suffix) slash--; if (git_str_grow(path, slash + 1 + strlen(prefix) + - GIT_OID_HEXSZ + strlen(suffix) + 1) < 0) + git_oid_hexsize(idx->oid_type) + strlen(suffix) + 1) < 0) return -1; git_str_truncate(path, slash); @@ -917,7 +975,7 @@ static int index_path(git_str *path, git_indexer *idx, const char *suffix) */ static int seek_back_trailer(git_indexer *idx) { - idx->pack->mwf.size -= GIT_OID_RAWSZ; + idx->pack->mwf.size -= git_oid_size(idx->oid_type); return git_mwindow_free_all(&idx->pack->mwf); } @@ -926,15 +984,17 @@ static int inject_object(git_indexer *idx, git_oid *id) git_odb_object *obj = NULL; struct entry *entry = NULL; struct git_pack_entry *pentry = NULL; - unsigned char empty_checksum[GIT_HASH_SHA1_SIZE] = {0}; + unsigned char empty_checksum[GIT_HASH_MAX_SIZE] = {0}; unsigned char hdr[64]; git_str buf = GIT_STR_INIT; off64_t entry_start; const void *data; size_t len, hdr_len; - size_t checksum_size = GIT_HASH_SHA1_SIZE; + size_t checksum_size; int error; + checksum_size = git_hash_size(indexer_hash_algorithm(idx)); + if ((error = seek_back_trailer(idx)) < 0) goto cleanup; @@ -977,12 +1037,12 @@ static int inject_object(git_indexer *idx, git_oid *id) if ((error = append_to_pack(idx, empty_checksum, checksum_size)) < 0) goto cleanup; - idx->pack->mwf.size += GIT_OID_RAWSZ; + idx->pack->mwf.size += git_oid_size(idx->oid_type); pentry = git__calloc(1, sizeof(struct git_pack_entry)); GIT_ERROR_CHECK_ALLOC(pentry); - git_oid_cpy(&pentry->sha1, id); + git_oid_cpy(&pentry->id, id); git_oid_cpy(&entry->oid, id); idx->off = entry_start + hdr_len + len; @@ -1040,13 +1100,13 @@ static int fix_thin_pack(git_indexer *idx, git_indexer_progress *stats) } /* curpos now points to the base information, which is an OID */ - base_info = git_mwindow_open(&idx->pack->mwf, &w, curpos, GIT_OID_RAWSZ, &left); + base_info = git_mwindow_open(&idx->pack->mwf, &w, curpos, git_oid_size(idx->oid_type), &left); if (base_info == NULL) { git_error_set(GIT_ERROR_INDEXER, "failed to map delta information"); return -1; } - git_oid_fromraw(&base, base_info); + git_oid__fromraw(&base, base_info, idx->oid_type); git_mwindow_close(&w); if (has_entry(idx, &base)) @@ -1168,10 +1228,10 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats) struct git_pack_idx_header hdr; git_str filename = GIT_STR_INIT; struct entry *entry; - unsigned char checksum[GIT_HASH_SHA1_SIZE]; + unsigned char checksum[GIT_HASH_MAX_SIZE]; git_filebuf index_file = {0}; void *packfile_trailer; - size_t checksum_size = GIT_HASH_SHA1_SIZE; + size_t checksum_size; bool mismatch; if (!idx->parsed_header) { @@ -1179,6 +1239,9 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats) return -1; } + checksum_size = git_hash_size(indexer_hash_algorithm(idx)); + GIT_ASSERT(checksum_size); + /* Test for this before resolve_deltas(), as it plays with idx->off */ if (idx->off + (ssize_t)checksum_size < idx->pack->mwf.size) { git_error_set(GIT_ERROR_INDEXER, "unexpected data at the end of the pack"); @@ -1269,7 +1332,7 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats) /* Write out the object names (SHA-1 hashes) */ git_vector_foreach(&idx->objects, i, entry) { - git_filebuf_write(&index_file, &entry->oid.id, GIT_OID_RAWSZ); + git_filebuf_write(&index_file, &entry->oid.id, git_oid_size(idx->oid_type)); } /* Write out the CRC32 values */ diff --git a/src/libgit2/iterator.c b/src/libgit2/iterator.c index bc6f766ce..1ee8e25f5 100644 --- a/src/libgit2/iterator.c +++ b/src/libgit2/iterator.c @@ -1271,7 +1271,7 @@ static int filesystem_iterator_entry_hash( int error; if (S_ISDIR(entry->st.st_mode)) { - memset(&entry->id, 0, GIT_OID_RAWSZ); + memset(&entry->id, 0, GIT_OID_SHA1_SIZE); return 0; } @@ -1281,7 +1281,7 @@ static int filesystem_iterator_entry_hash( if (!(error = git_str_joinpath(&fullpath, iter->root, entry->path)) && !(error = git_path_validate_str_length(iter->base.repo, &fullpath))) - error = git_odb_hashfile(&entry->id, fullpath.ptr, GIT_OBJECT_BLOB); + error = git_odb__hashfile(&entry->id, fullpath.ptr, GIT_OBJECT_BLOB, GIT_OID_SHA1); git_str_dispose(&fullpath); return error; @@ -1529,6 +1529,8 @@ static void filesystem_iterator_set_current( if (iter->base.flags & GIT_ITERATOR_INCLUDE_HASH) git_oid_cpy(&iter->entry.id, &entry->id); + else + git_oid_clear(&iter->entry.id, GIT_OID_SHA1); iter->entry.path = entry->path; diff --git a/src/libgit2/libgit2.c b/src/libgit2/libgit2.c index 2fda0722e..f225122e5 100644 --- a/src/libgit2/libgit2.c +++ b/src/libgit2/libgit2.c @@ -414,6 +414,25 @@ int git_libgit2_opts(int key, ...) git_repository__validate_ownership = (va_arg(ap, int) != 0); break; + case GIT_OPT_GET_HOMEDIR: + { + git_buf *out = va_arg(ap, git_buf *); + git_str str = GIT_STR_INIT; + const git_str *tmp; + + if ((error = git_buf_tostr(&str, out)) < 0 || + (error = git_sysdir_get(&tmp, GIT_SYSDIR_HOME)) < 0 || + (error = git_str_put(&str, tmp->ptr, tmp->size)) < 0) + break; + + error = git_buf_fromstr(out, &str); + } + break; + + case GIT_OPT_SET_HOMEDIR: + error = git_sysdir_set(GIT_SYSDIR_HOME, va_arg(ap, const char *)); + break; + default: git_error_set(GIT_ERROR_INVALID, "invalid option key"); error = -1; diff --git a/src/libgit2/merge.c b/src/libgit2/merge.c index 641b32632..df2cefb29 100644 --- a/src/libgit2/merge.c +++ b/src/libgit2/merge.c @@ -611,13 +611,13 @@ int git_repository_mergehead_foreach( buffer = merge_head_file.ptr; while ((line = git__strsep(&buffer, "\n")) != NULL) { - if (strlen(line) != GIT_OID_HEXSZ) { + if (strlen(line) != GIT_OID_SHA1_HEXSIZE) { git_error_set(GIT_ERROR_INVALID, "unable to parse OID - invalid length"); error = -1; goto cleanup; } - if ((error = git_oid_fromstr(&oid, line)) < 0) + if ((error = git_oid__fromstr(&oid, line, GIT_OID_SHA1)) < 0) goto cleanup; if ((error = cb(&oid, payload)) != 0) { @@ -1061,7 +1061,7 @@ static int index_entry_similarity_calc( const git_merge_options *opts) { git_blob *blob; - git_diff_file diff_file = {{{0}}}; + git_diff_file diff_file = { GIT_OID_SHA1_ZERO }; git_object_size_t blobsize; int error; diff --git a/src/libgit2/midx.c b/src/libgit2/midx.c index 67eab9acb..b09055237 100644 --- a/src/libgit2/midx.c +++ b/src/libgit2/midx.c @@ -115,19 +115,19 @@ static int midx_parse_oid_lookup( struct git_midx_chunk *chunk_oid_lookup) { uint32_t i; - unsigned char *oid, *prev_oid, zero_oid[GIT_OID_RAWSZ] = {0}; + unsigned char *oid, *prev_oid, zero_oid[GIT_OID_SHA1_SIZE] = {0}; if (chunk_oid_lookup->offset == 0) return midx_error("missing OID Lookup chunk"); if (chunk_oid_lookup->length == 0) return midx_error("empty OID Lookup chunk"); - if (chunk_oid_lookup->length != idx->num_objects * GIT_OID_RAWSZ) + if (chunk_oid_lookup->length != idx->num_objects * GIT_OID_SHA1_SIZE) return midx_error("OID Lookup chunk has wrong length"); idx->oid_lookup = oid = (unsigned char *)(data + chunk_oid_lookup->offset); prev_oid = zero_oid; - for (i = 0; i < idx->num_objects; ++i, oid += GIT_OID_RAWSZ) { - if (git_oid_raw_cmp(prev_oid, oid) >= 0) + for (i = 0; i < idx->num_objects; ++i, oid += GIT_OID_SHA1_SIZE) { + if (git_oid_raw_cmp(prev_oid, oid, GIT_OID_SHA1_SIZE) >= 0) return midx_error("OID Lookup index is non-monotonic"); prev_oid = oid; } @@ -188,7 +188,7 @@ int git_midx_parse( GIT_ASSERT_ARG(idx); - if (size < sizeof(struct git_midx_header) + GIT_OID_RAWSZ) + if (size < sizeof(struct git_midx_header) + GIT_OID_SHA1_SIZE) return midx_error("multi-pack index is too short"); hdr = ((struct git_midx_header *)data); @@ -365,7 +365,7 @@ bool git_midx_needs_refresh( } checksum_size = GIT_HASH_SHA1_SIZE; - bytes_read = p_pread(fd, checksum, checksum_size, st.st_size - GIT_OID_RAWSZ); + bytes_read = p_pread(fd, checksum, checksum_size, st.st_size - GIT_OID_SHA1_SIZE); p_close(fd); if (bytes_read != (ssize_t)checksum_size) @@ -392,27 +392,27 @@ int git_midx_entry_find( hi = ntohl(idx->oid_fanout[(int)short_oid->id[0]]); lo = ((short_oid->id[0] == 0x0) ? 0 : ntohl(idx->oid_fanout[(int)short_oid->id[0] - 1])); - pos = git_pack__lookup_sha1(idx->oid_lookup, GIT_OID_RAWSZ, lo, hi, short_oid->id); + pos = git_pack__lookup_id(idx->oid_lookup, GIT_OID_SHA1_SIZE, lo, hi, short_oid->id, GIT_OID_SHA1); if (pos >= 0) { /* An object matching exactly the oid was found */ found = 1; - current = idx->oid_lookup + (pos * GIT_OID_RAWSZ); + current = idx->oid_lookup + (pos * GIT_OID_SHA1_SIZE); } else { /* No object was found */ /* pos refers to the object with the "closest" oid to short_oid */ pos = -1 - pos; if (pos < (int)idx->num_objects) { - current = idx->oid_lookup + (pos * GIT_OID_RAWSZ); + current = idx->oid_lookup + (pos * GIT_OID_SHA1_SIZE); if (!git_oid_raw_ncmp(short_oid->id, current, len)) found = 1; } } - if (found && len != GIT_OID_HEXSZ && pos + 1 < (int)idx->num_objects) { + if (found && len != GIT_OID_SHA1_HEXSIZE && pos + 1 < (int)idx->num_objects) { /* Check for ambiguousity */ - const unsigned char *next = current + GIT_OID_RAWSZ; + const unsigned char *next = current + GIT_OID_SHA1_SIZE; if (!git_oid_raw_ncmp(short_oid->id, next, len)) found = 2; @@ -443,7 +443,7 @@ int git_midx_entry_find( return midx_error("invalid index into the packfile names table"); e->pack_index = pack_index; e->offset = offset; - git_oid_fromraw(&e->sha1, current); + git_oid__fromraw(&e->sha1, current, GIT_OID_SHA1); return 0; } @@ -459,7 +459,7 @@ int git_midx_foreach_entry( GIT_ASSERT_ARG(idx); for (i = 0; i < idx->num_objects; ++i) { - if ((error = git_oid_fromraw(&oid, &idx->oid_lookup[i * GIT_OID_RAWSZ])) < 0) + if ((error = git_oid__fromraw(&oid, &idx->oid_lookup[i * GIT_OID_SHA1_SIZE], GIT_OID_SHA1)) < 0) return error; if ((error = cb(&oid, data)) != 0) @@ -549,7 +549,8 @@ int git_midx_writer_add( if (error < 0) return error; - error = git_mwindow_get_pack(&p, git_str_cstr(&idx_path_buf)); + /* TODO: SHA256 */ + error = git_mwindow_get_pack(&p, git_str_cstr(&idx_path_buf), 0); git_str_dispose(&idx_path_buf); if (error < 0) return error; @@ -748,7 +749,7 @@ static int midx_write( /* Fill the OID Lookup table. */ git_vector_foreach (&object_entries, i, entry) { - error = git_str_put(&oid_lookup, (char *)&entry->sha1.id, GIT_OID_RAWSZ); + error = git_str_put(&oid_lookup, (char *)&entry->sha1.id, GIT_OID_SHA1_SIZE); if (error < 0) goto cleanup; } diff --git a/src/libgit2/mwindow.c b/src/libgit2/mwindow.c index ad649490a..b8295d9d1 100644 --- a/src/libgit2/mwindow.c +++ b/src/libgit2/mwindow.c @@ -61,7 +61,10 @@ int git_mwindow_global_init(void) return git_runtime_shutdown_register(git_mwindow_global_shutdown); } -int git_mwindow_get_pack(struct git_pack_file **out, const char *path) +int git_mwindow_get_pack( + struct git_pack_file **out, + const char *path, + git_oid_t oid_type) { struct git_pack_file *pack; char *packname; @@ -86,7 +89,7 @@ int git_mwindow_get_pack(struct git_pack_file **out, const char *path) } /* If we didn't find it, we need to create it */ - if ((error = git_packfile_alloc(&pack, path)) < 0) { + if ((error = git_packfile_alloc(&pack, path, oid_type)) < 0) { git_mutex_unlock(&git__mwindow_mutex); return error; } diff --git a/src/libgit2/mwindow.h b/src/libgit2/mwindow.h index e32ab99d4..8e6df2613 100644 --- a/src/libgit2/mwindow.h +++ b/src/libgit2/mwindow.h @@ -48,7 +48,10 @@ void git_mwindow_close(git_mwindow **w_cursor); extern int git_mwindow_global_init(void); struct git_pack_file; /* just declaration to avoid cyclical includes */ -int git_mwindow_get_pack(struct git_pack_file **out, const char *path); +int git_mwindow_get_pack( + struct git_pack_file **out, + const char *path, + git_oid_t oid_type); int git_mwindow_put_pack(struct git_pack_file *pack); #endif diff --git a/src/libgit2/notes.c b/src/libgit2/notes.c index d1a2b0f64..1b1935330 100644 --- a/src/libgit2/notes.c +++ b/src/libgit2/notes.c @@ -460,7 +460,7 @@ int git_note_commit_read( { int error; git_tree *tree = NULL; - char target[GIT_OID_HEXSZ + 1]; + char target[GIT_OID_SHA1_HEXSIZE + 1]; git_oid_tostr(target, sizeof(target), oid); @@ -507,7 +507,7 @@ int git_note_commit_create( { int error; git_tree *tree = NULL; - char target[GIT_OID_HEXSZ + 1]; + char target[GIT_OID_SHA1_HEXSIZE + 1]; git_oid_tostr(target, sizeof(target), oid); @@ -578,7 +578,7 @@ int git_note_commit_remove( { int error; git_tree *tree = NULL; - char target[GIT_OID_HEXSZ + 1]; + char target[GIT_OID_SHA1_HEXSIZE + 1]; git_oid_tostr(target, sizeof(target), oid); @@ -698,12 +698,12 @@ static int process_entry_path( buf.ptr[j] = '\0'; buf.size = j; - if (j != GIT_OID_HEXSZ) { + if (j != GIT_OID_SHA1_HEXSIZE) { /* This is not a note entry */ goto cleanup; } - error = git_oid_fromstr(annotated_object_id, buf.ptr); + error = git_oid__fromstr(annotated_object_id, buf.ptr, GIT_OID_SHA1); cleanup: git_str_dispose(&buf); diff --git a/src/libgit2/object.c b/src/libgit2/object.c index b828f88f6..d87d40cf1 100644 --- a/src/libgit2/object.c +++ b/src/libgit2/object.c @@ -21,15 +21,14 @@ bool git_object__strict_input_validation = true; -extern int git_odb_hash(git_oid *out, const void *data, size_t len, git_object_t type); size_t git_object__size(git_object_t type); typedef struct { const char *str; /* type name string */ size_t size; /* size in bytes of the object structure */ - int (*parse)(void *self, git_odb_object *obj); - int (*parse_raw)(void *self, const char *data, size_t size); + int (*parse)(void *self, git_odb_object *obj, git_oid_t oid_type); + int (*parse_raw)(void *self, const char *data, size_t size, git_oid_t oid_type); void (*free)(void *self); } git_object_def; @@ -61,7 +60,8 @@ int git_object__from_raw( git_object **object_out, const char *data, size_t size, - git_object_t type) + git_object_t object_type, + git_oid_t oid_type) { git_object_def *def; git_object *object; @@ -72,12 +72,15 @@ int git_object__from_raw( *object_out = NULL; /* Validate type match */ - if (type != GIT_OBJECT_BLOB && type != GIT_OBJECT_TREE && type != GIT_OBJECT_COMMIT && type != GIT_OBJECT_TAG) { + if (object_type != GIT_OBJECT_BLOB && + object_type != GIT_OBJECT_TREE && + object_type != GIT_OBJECT_COMMIT && + object_type != GIT_OBJECT_TAG) { git_error_set(GIT_ERROR_INVALID, "the requested type is invalid"); return GIT_ENOTFOUND; } - if ((object_size = git_object__size(type)) == 0) { + if ((object_size = git_object__size(object_type)) == 0) { git_error_set(GIT_ERROR_INVALID, "the requested type is invalid"); return GIT_ENOTFOUND; } @@ -86,15 +89,15 @@ int git_object__from_raw( object = git__calloc(1, object_size); GIT_ERROR_CHECK_ALLOC(object); object->cached.flags = GIT_CACHE_STORE_PARSED; - object->cached.type = type; - if ((error = git_odb_hash(&object->cached.oid, data, size, type)) < 0) + object->cached.type = object_type; + if ((error = git_odb__hash(&object->cached.oid, data, size, object_type, oid_type)) < 0) return error; /* Parse raw object data */ - def = &git_objects_table[type]; + def = &git_objects_table[object_type]; GIT_ASSERT(def->free && def->parse_raw); - if ((error = def->parse_raw(object, data, size)) < 0) { + if ((error = def->parse_raw(object, data, size, oid_type)) < 0) { def->free(object); return error; } @@ -144,7 +147,7 @@ int git_object__from_odb_object( def = &git_objects_table[odb_obj->cached.type]; GIT_ASSERT(def->free && def->parse); - if ((error = def->parse(object, odb_obj)) < 0) { + if ((error = def->parse(object, odb_obj, repo->oid_type)) < 0) { /* * parse returns EINVALID on invalid data; downgrade * that to a normal -1 error code. @@ -193,10 +196,10 @@ int git_object_lookup_prefix( if (error < 0) return error; - if (len > GIT_OID_HEXSZ) - len = GIT_OID_HEXSZ; + if (len > GIT_OID_SHA1_HEXSIZE) + len = GIT_OID_SHA1_HEXSIZE; - if (len == GIT_OID_HEXSZ) { + if (len == GIT_OID_SHA1_HEXSIZE) { git_cached_obj *cached = NULL; /* We want to match the full id : we can first look up in the cache, @@ -230,11 +233,11 @@ int git_object_lookup_prefix( error = git_odb_read(&odb_obj, odb, id); } } else { - git_oid short_oid = {{ 0 }}; + git_oid short_oid = GIT_OID_SHA1_ZERO; git_oid__cpy_prefix(&short_oid, id, len); - /* If len < GIT_OID_HEXSZ (a strict short oid was given), we have + /* If len < GIT_OID_SHA1_HEXSIZE (a strict short oid was given), we have * 2 options : * - We always search in the cache first. If we find that short oid is * ambiguous, we can stop. But in all the other cases, we must then @@ -259,7 +262,7 @@ int git_object_lookup_prefix( } int git_object_lookup(git_object **object_out, git_repository *repo, const git_oid *id, git_object_t type) { - return git_object_lookup_prefix(object_out, repo, id, GIT_OID_HEXSZ, type); + return git_object_lookup_prefix(object_out, repo, id, GIT_OID_SHA1_HEXSIZE, type); } void git_object_free(git_object *object) @@ -358,12 +361,11 @@ static int dereference_object(git_object **dereferenced, git_object *obj) static int peel_error(int error, const git_oid *oid, git_object_t type) { const char *type_name; - char hex_oid[GIT_OID_HEXSZ + 1]; + char hex_oid[GIT_OID_MAX_HEXSIZE + 1]; type_name = git_object_type2string(type); - git_oid_fmt(hex_oid, oid); - hex_oid[GIT_OID_HEXSZ] = '\0'; + git_oid_nfmt(hex_oid, GIT_OID_MAX_HEXSIZE + 1, oid); git_error_set(GIT_ERROR_OBJECT, "the git_object of id '%s' can not be " "successfully peeled into a %s (git_object_t=%i).", hex_oid, type_name, type); @@ -502,7 +504,7 @@ static int git_object__short_id(git_str *out, const git_object *obj) { git_repository *repo; int len = GIT_ABBREV_DEFAULT, error; - git_oid id = {{0}}; + git_oid id = GIT_OID_SHA1_ZERO; git_odb *odb; GIT_ASSERT_ARG(out); @@ -516,12 +518,16 @@ static int git_object__short_id(git_str *out, const git_object *obj) if ((error = git_repository_odb(&odb, repo)) < 0) return error; - while (len < GIT_OID_HEXSZ) { + while (len < GIT_OID_SHA1_HEXSIZE) { /* set up short oid */ memcpy(&id.id, &obj->cached.oid.id, (len + 1) / 2); if (len & 1) id.id[len / 2] &= 0xf0; +#ifdef GIT_EXPERIMENTAL_SHA256 + id.type = GIT_OID_SHA1; +#endif + error = git_odb_exists_prefix(NULL, odb, &id, len); if (error != GIT_EAMBIGUOUS) break; @@ -573,21 +579,29 @@ int git_object_rawcontent_is_valid( int *valid, const char *buf, size_t len, - git_object_t type) + git_object_t object_type +#ifdef GIT_EXPERIMENTAL_SHA256 + , git_oid_t oid_type +#endif + ) { git_object *obj = NULL; int error; +#ifndef GIT_EXPERIMENTAL_SHA256 + git_oid_t oid_type = GIT_OID_SHA1; +#endif + GIT_ASSERT_ARG(valid); GIT_ASSERT_ARG(buf); /* Blobs are always valid; don't bother parsing. */ - if (type == GIT_OBJECT_BLOB) { + if (object_type == GIT_OBJECT_BLOB) { *valid = 1; return 0; } - error = git_object__from_raw(&obj, buf, len, type); + error = git_object__from_raw(&obj, buf, len, object_type, oid_type); git_object_free(obj); if (error == 0) { @@ -600,3 +614,53 @@ int git_object_rawcontent_is_valid( return error; } + +int git_object__parse_oid_header( + git_oid *oid, + const char **buffer_out, + const char *buffer_end, + const char *header, + git_oid_t oid_type) +{ + const size_t sha_len = git_oid_hexsize(oid_type); + const size_t header_len = strlen(header); + + const char *buffer = *buffer_out; + + if (buffer + (header_len + sha_len + 1) > buffer_end) + return -1; + + if (memcmp(buffer, header, header_len) != 0) + return -1; + + if (buffer[header_len + sha_len] != '\n') + return -1; + + if (git_oid__fromstr(oid, buffer + header_len, oid_type) < 0) + return -1; + + *buffer_out = buffer + (header_len + sha_len + 1); + + return 0; +} + +int git_object__write_oid_header( + git_str *buf, + const char *header, + const git_oid *oid) +{ + size_t hex_size = git_oid_hexsize(git_oid_type(oid)); + char hex_oid[GIT_OID_MAX_HEXSIZE]; + + if (!hex_size) { + git_error_set(GIT_ERROR_INVALID, "unknown type"); + return -1; + } + + git_oid_fmt(hex_oid, oid); + git_str_puts(buf, header); + git_str_put(buf, hex_oid, hex_size); + git_str_putc(buf, '\n'); + + return git_str_oom(buf) ? -1 : 0; +} diff --git a/src/libgit2/object.h b/src/libgit2/object.h index 66be57557..a29fdfbf3 100644 --- a/src/libgit2/object.h +++ b/src/libgit2/object.h @@ -33,7 +33,8 @@ int git_object__from_raw( git_object **object_out, const char *data, size_t size, - git_object_t type); + git_object_t object_type, + git_oid_t oid_type); int git_object__from_odb_object( git_object **object_out, @@ -45,9 +46,17 @@ int git_object__resolve_to_type(git_object **obj, git_object_t type); git_object_t git_object_stringn2type(const char *str, size_t len); -int git_oid__parse(git_oid *oid, const char **buffer_out, const char *buffer_end, const char *header); +int git_object__parse_oid_header( + git_oid *oid, + const char **buffer_out, + const char *buffer_end, + const char *header, + git_oid_t oid_type); -void git_oid__writebuf(git_str *buf, const char *header, const git_oid *oid); +int git_object__write_oid_header( + git_str *buf, + const char *header, + const git_oid *oid); bool git_object__is_valid( git_repository *repo, const git_oid *id, git_object_t expected_type); diff --git a/src/libgit2/odb.c b/src/libgit2/odb.c index 7b98c72ee..0fc48035a 100644 --- a/src/libgit2/odb.c +++ b/src/libgit2/odb.c @@ -105,11 +105,12 @@ int git_odb__format_object_header( return 0; } -int git_odb__hashobj(git_oid *id, git_rawobj *obj) +int git_odb__hashobj(git_oid *id, git_rawobj *obj, git_oid_t oid_type) { git_str_vec vec[2]; char header[64]; size_t hdrlen; + git_hash_algorithm_t algorithm; int error; GIT_ASSERT_ARG(id); @@ -120,6 +121,11 @@ int git_odb__hashobj(git_oid *id, git_rawobj *obj) return -1; } + if (!(algorithm = git_oid_algorithm(oid_type))) { + git_error_set(GIT_ERROR_INVALID, "unknown oid type"); + return -1; + } + if (!obj->data && obj->len != 0) { git_error_set(GIT_ERROR_INVALID, "invalid object"); return -1; @@ -134,7 +140,11 @@ int git_odb__hashobj(git_oid *id, git_rawobj *obj) vec[1].data = obj->data; vec[1].len = obj->len; - return git_hash_vec(id->id, vec, 2, GIT_HASH_ALGORITHM_SHA1); +#ifdef GIT_EXPERIMENTAL_SHA256 + id->type = oid_type; +#endif + + return git_hash_vec(id->id, vec, 2, algorithm); } @@ -195,24 +205,35 @@ void git_odb_object_free(git_odb_object *object) git_cached_obj_decref(object); } -int git_odb__hashfd(git_oid *out, git_file fd, size_t size, git_object_t type) +int git_odb__hashfd( + git_oid *out, + git_file fd, + size_t size, + git_object_t object_type, + git_oid_t oid_type) { size_t hdr_len; char hdr[64], buffer[GIT_BUFSIZE_FILEIO]; git_hash_ctx ctx; + git_hash_algorithm_t algorithm; ssize_t read_len = 0; int error = 0; - if (!git_object_typeisloose(type)) { + if (!git_object_typeisloose(object_type)) { git_error_set(GIT_ERROR_INVALID, "invalid object type for hash"); return -1; } - if ((error = git_hash_ctx_init(&ctx, GIT_HASH_ALGORITHM_SHA1)) < 0) + if (!(algorithm = git_oid_algorithm(oid_type))) { + git_error_set(GIT_ERROR_INVALID, "unknown oid type"); + return -1; + } + + if ((error = git_hash_ctx_init(&ctx, algorithm)) < 0) return error; if ((error = git_odb__format_object_header(&hdr_len, hdr, - sizeof(hdr), size, type)) < 0) + sizeof(hdr), size, object_type)) < 0) goto done; if ((error = git_hash_update(&ctx, hdr, hdr_len)) < 0) @@ -237,19 +258,28 @@ int git_odb__hashfd(git_oid *out, git_file fd, size_t size, git_object_t type) error = git_hash_final(out->id, &ctx); +#ifdef GIT_EXPERIMENTAL_SHA256 + out->type = oid_type; +#endif + done: git_hash_ctx_cleanup(&ctx); return error; } int git_odb__hashfd_filtered( - git_oid *out, git_file fd, size_t size, git_object_t type, git_filter_list *fl) + git_oid *out, + git_file fd, + size_t size, + git_object_t object_type, + git_oid_t oid_type, + git_filter_list *fl) { int error; git_str raw = GIT_STR_INIT; if (!fl) - return git_odb__hashfd(out, fd, size, type); + return git_odb__hashfd(out, fd, size, object_type, oid_type); /* size of data is used in header, so we have to read the whole file * into memory to apply filters before beginning to calculate the hash @@ -261,7 +291,7 @@ int git_odb__hashfd_filtered( error = git_filter_list__convert_buf(&post, fl, &raw); if (!error) - error = git_odb_hash(out, post.ptr, post.size, type); + error = git_odb__hash(out, post.ptr, post.size, object_type, oid_type); git_str_dispose(&post); } @@ -269,7 +299,7 @@ int git_odb__hashfd_filtered( return error; } -int git_odb__hashlink(git_oid *out, const char *path) +int git_odb__hashlink(git_oid *out, const char *path, git_oid_t oid_type) { struct stat st; int size; @@ -303,20 +333,24 @@ int git_odb__hashlink(git_oid *out, const char *path) GIT_ASSERT(read_len <= size); link_data[read_len] = '\0'; - result = git_odb_hash(out, link_data, read_len, GIT_OBJECT_BLOB); + result = git_odb__hash(out, link_data, read_len, GIT_OBJECT_BLOB, oid_type); git__free(link_data); } else { int fd = git_futils_open_ro(path); if (fd < 0) return -1; - result = git_odb__hashfd(out, fd, size, GIT_OBJECT_BLOB); + result = git_odb__hashfd(out, fd, size, GIT_OBJECT_BLOB, oid_type); p_close(fd); } return result; } -int git_odb_hashfile(git_oid *out, const char *path, git_object_t type) +int git_odb__hashfile( + git_oid *out, + const char *path, + git_object_t object_type, + git_oid_t oid_type) { uint64_t size; int fd, error = 0; @@ -333,14 +367,38 @@ int git_odb_hashfile(git_oid *out, const char *path, git_object_t type) goto done; } - error = git_odb__hashfd(out, fd, (size_t)size, type); + error = git_odb__hashfd(out, fd, (size_t)size, object_type, oid_type); done: p_close(fd); return error; } -int git_odb_hash(git_oid *id, const void *data, size_t len, git_object_t type) +#ifdef GIT_EXPERIMENTAL_SHA256 +int git_odb_hashfile( + git_oid *out, + const char *path, + git_object_t object_type, + git_oid_t oid_type) +{ + return git_odb__hashfile(out, path, object_type, oid_type); +} +#else +int git_odb_hashfile( + git_oid *out, + const char *path, + git_object_t object_type) +{ + return git_odb__hashfile(out, path, object_type, GIT_OID_SHA1); +} +#endif + +int git_odb__hash( + git_oid *id, + const void *data, + size_t len, + git_object_t object_type, + git_oid_t oid_type) { git_rawobj raw; @@ -348,11 +406,32 @@ int git_odb_hash(git_oid *id, const void *data, size_t len, git_object_t type) raw.data = (void *)data; raw.len = len; - raw.type = type; + raw.type = object_type; - return git_odb__hashobj(id, &raw); + return git_odb__hashobj(id, &raw, oid_type); } +#ifdef GIT_EXPERIMENTAL_SHA256 +int git_odb_hash( + git_oid *out, + const void *data, + size_t len, + git_object_t object_type, + git_oid_t oid_type) +{ + return git_odb__hash(out, data, len, object_type, oid_type); +} +#else +int git_odb_hash( + git_oid *out, + const void *data, + size_t len, + git_object_t type) +{ + return git_odb__hash(out, data, len, type, GIT_OID_SHA1); +} +#endif + /** * FAKE WSTREAM */ @@ -442,11 +521,28 @@ static int backend_sort_cmp(const void *a, const void *b) return (backend_b->priority - backend_a->priority); } -int git_odb_new(git_odb **out) +static void normalize_options( + git_odb_options *opts, + const git_odb_options *given_opts) +{ + git_odb_options init = GIT_ODB_OPTIONS_INIT; + + if (given_opts) + memcpy(opts, given_opts, sizeof(git_odb_options)); + else + memcpy(opts, &init, sizeof(git_odb_options)); + + if (!opts->oid_type) + opts->oid_type = GIT_OID_DEFAULT; +} + +int git_odb__new(git_odb **out, const git_odb_options *opts) { git_odb *db = git__calloc(1, sizeof(*db)); GIT_ERROR_CHECK_ALLOC(db); + normalize_options(&db->options, opts); + if (git_mutex_init(&db->lock) < 0) { git__free(db); return -1; @@ -468,6 +564,18 @@ int git_odb_new(git_odb **out) return 0; } +#ifdef GIT_EXPERIMENTAL_SHA256 +int git_odb_new(git_odb **out, const git_odb_options *opts) +{ + return git_odb__new(out, opts); +} +#else +int git_odb_new(git_odb **out) +{ + return git_odb__new(out, NULL); +} +#endif + static int add_backend_internal( git_odb *odb, git_odb_backend *backend, int priority, bool is_alternate, ino_t disk_inode) @@ -575,6 +683,8 @@ int git_odb__add_default_backends( struct stat st; ino_t inode; git_odb_backend *loose, *packed; + git_odb_backend_loose_options loose_opts = GIT_ODB_BACKEND_LOOSE_OPTIONS_INIT; + git_odb_backend_pack_options pack_opts = GIT_ODB_BACKEND_PACK_OPTIONS_INIT; /* TODO: inodes are not really relevant on Win32, so we need to find * a cross-platform workaround for this */ @@ -609,14 +719,29 @@ int git_odb__add_default_backends( git_mutex_unlock(&db->lock); #endif + if (db->do_fsync) + loose_opts.flags |= GIT_ODB_BACKEND_LOOSE_FSYNC; + + loose_opts.oid_type = db->options.oid_type; + pack_opts.oid_type = db->options.oid_type; + /* add the loose object backend */ - if (git_odb_backend_loose(&loose, objects_dir, -1, db->do_fsync, 0, 0) < 0 || + if (git_odb__backend_loose(&loose, objects_dir, &loose_opts) < 0 || add_backend_internal(db, loose, git_odb__loose_priority, as_alternates, inode) < 0) return -1; /* add the packed file backend */ - if (git_odb_backend_pack(&packed, objects_dir) < 0 || - add_backend_internal(db, packed, git_odb__packed_priority, as_alternates, inode) < 0) +#ifdef GIT_EXPERIMENTAL_SHA256 + if (git_odb_backend_pack(&packed, objects_dir, &pack_opts) < 0) + return -1; +#else + GIT_UNUSED(pack_opts); + + if (git_odb_backend_pack(&packed, objects_dir) < 0) + return -1; +#endif + + if (add_backend_internal(db, packed, git_odb__packed_priority, as_alternates, inode) < 0) return -1; if (git_mutex_lock(&db->lock) < 0) { @@ -707,7 +832,10 @@ int git_odb_set_commit_graph(git_odb *odb, git_commit_graph *cgraph) return error; } -int git_odb_open(git_odb **out, const char *objects_dir) +int git_odb__open( + git_odb **out, + const char *objects_dir, + const git_odb_options *opts) { git_odb *db; @@ -716,7 +844,7 @@ int git_odb_open(git_odb **out, const char *objects_dir) *out = NULL; - if (git_odb_new(&db) < 0) + if (git_odb__new(&db, opts) < 0) return -1; if (git_odb__add_default_backends(db, objects_dir, 0, 0) < 0) { @@ -728,6 +856,25 @@ int git_odb_open(git_odb **out, const char *objects_dir) return 0; } +#ifdef GIT_EXPERIMENTAL_SHA256 + +int git_odb_open( + git_odb **out, + const char *objects_dir, + const git_odb_options *opts) +{ + return git_odb__open(out, objects_dir, opts); +} + +#else + +int git_odb_open(git_odb **out, const char *objects_dir) +{ + return git_odb__open(out, objects_dir, NULL); +} + +#endif + int git_odb__set_caps(git_odb *odb, int caps) { if (caps == GIT_ODB_CAP_FROM_OWNER) { @@ -914,7 +1061,7 @@ static int odb_exists_prefix_1(git_oid *out, git_odb *db, { size_t i; int error = GIT_ENOTFOUND, num_found = 0; - git_oid last_found = {{0}}, found; + git_oid last_found = GIT_OID_NONE, found; if ((error = git_mutex_lock(&db->lock)) < 0) { git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock"); @@ -965,7 +1112,7 @@ int git_odb_exists_prefix( git_oid *out, git_odb *db, const git_oid *short_id, size_t len) { int error; - git_oid key = {{0}}; + git_oid key = GIT_OID_NONE; GIT_ASSERT_ARG(db); GIT_ASSERT_ARG(short_id); @@ -973,7 +1120,7 @@ int git_odb_exists_prefix( if (len < GIT_OID_MINPREFIXLEN) return git_odb__error_ambiguous("prefix length too short"); - if (len >= GIT_OID_HEXSZ) { + if (len >= git_oid_hexsize(db->options.oid_type)) { if (git_odb_exists(db, short_id)) { if (out) git_oid_cpy(out, short_id); @@ -1002,11 +1149,13 @@ int git_odb_expand_ids( git_odb_expand_id *ids, size_t count) { - size_t i; + size_t hex_size, i; GIT_ASSERT_ARG(db); GIT_ASSERT_ARG(ids); + hex_size = git_oid_hexsize(db->options.oid_type); + for (i = 0; i < count; i++) { git_odb_expand_id *query = &ids[i]; int error = GIT_EAMBIGUOUS; @@ -1015,13 +1164,13 @@ int git_odb_expand_ids( query->type = GIT_OBJECT_ANY; /* if we have a short OID, expand it first */ - if (query->length >= GIT_OID_MINPREFIXLEN && query->length < GIT_OID_HEXSZ) { + if (query->length >= GIT_OID_MINPREFIXLEN && query->length < hex_size) { git_oid actual_id; error = odb_exists_prefix_1(&actual_id, db, &query->id, query->length, false); if (!error) { git_oid_cpy(&query->id, &actual_id); - query->length = GIT_OID_HEXSZ; + query->length = (unsigned short)hex_size; } } @@ -1029,7 +1178,7 @@ int git_odb_expand_ids( * now we ought to have a 40-char OID, either because we've expanded it * or because the user passed a full OID. Ensure its type is right. */ - if (query->length >= GIT_OID_HEXSZ) { + if (query->length >= hex_size) { git_object_t actual_type; error = odb_otype_fast(&actual_type, db, &query->id); @@ -1049,7 +1198,7 @@ int git_odb_expand_ids( /* the object is missing or ambiguous */ case GIT_ENOTFOUND: case GIT_EAMBIGUOUS: - memset(&query->id, 0, sizeof(git_oid)); + git_oid_clear(&query->id, db->options.oid_type); query->length = 0; query->type = 0; break; @@ -1157,7 +1306,7 @@ int git_odb__read_header_or_object( error = odb_read_header_1(len_p, type_p, db, id, true); if (error == GIT_ENOTFOUND) - return git_odb__error_notfound("cannot read header for", id, GIT_OID_HEXSZ); + return git_odb__error_notfound("cannot read header for", id, git_oid_hexsize(db->options.oid_type)); /* we found the header; return early */ if (!error) @@ -1179,8 +1328,11 @@ int git_odb__read_header_or_object( return error; } -static int odb_read_1(git_odb_object **out, git_odb *db, const git_oid *id, - bool only_refreshed) +static int odb_read_1( + git_odb_object **out, + git_odb *db, + const git_oid *id, + bool only_refreshed) { size_t i; git_rawobj raw; @@ -1224,7 +1376,7 @@ static int odb_read_1(git_odb_object **out, git_odb *db, const git_oid *id, return GIT_ENOTFOUND; if (git_odb__strict_hash_verification) { - if ((error = git_odb_hash(&hashed, raw.data, raw.len, raw.type)) < 0) + if ((error = git_odb__hash(&hashed, raw.data, raw.len, raw.type, db->options.oid_type)) < 0) goto out; if (!git_oid_equal(id, &hashed)) { @@ -1268,7 +1420,7 @@ int git_odb_read(git_odb_object **out, git_odb *db, const git_oid *id) error = odb_read_1(out, db, id, true); if (error == GIT_ENOTFOUND) - return git_odb__error_notfound("no match for id", id, GIT_OID_HEXSZ); + return git_odb__error_notfound("no match for id", id, git_oid_hexsize(git_oid_type(id))); return error; } @@ -1305,7 +1457,7 @@ static int read_prefix_1(git_odb_object **out, git_odb *db, { size_t i; int error = 0; - git_oid found_full_oid = {{0}}; + git_oid found_full_oid = GIT_OID_NONE; git_rawobj raw = {0}; void *data = NULL; bool found = false; @@ -1365,7 +1517,7 @@ static int read_prefix_1(git_odb_object **out, git_odb *db, if (git_odb__strict_hash_verification) { git_oid hash; - if ((error = git_odb_hash(&hash, raw.data, raw.len, raw.type)) < 0) + if ((error = git_odb__hash(&hash, raw.data, raw.len, raw.type, db->options.oid_type)) < 0) goto out; if (!git_oid_equal(&found_full_oid, &hash)) { @@ -1391,19 +1543,22 @@ out: int git_odb_read_prefix( git_odb_object **out, git_odb *db, const git_oid *short_id, size_t len) { - git_oid key = {{0}}; + git_oid key = GIT_OID_NONE; + size_t hex_size; int error; GIT_ASSERT_ARG(out); GIT_ASSERT_ARG(db); + hex_size = git_oid_hexsize(db->options.oid_type); + if (len < GIT_OID_MINPREFIXLEN) return git_odb__error_ambiguous("prefix length too short"); - if (len > GIT_OID_HEXSZ) - len = GIT_OID_HEXSZ; + if (len > hex_size) + len = hex_size; - if (len == GIT_OID_HEXSZ) { + if (len == hex_size) { *out = git_cache_get_raw(odb_cache(db), short_id); if (*out != NULL) return 0; @@ -1463,7 +1618,7 @@ int git_odb_write( GIT_ASSERT_ARG(oid); GIT_ASSERT_ARG(db); - if ((error = git_odb_hash(oid, data, len, type)) < 0) + if ((error = git_odb__hash(oid, data, len, type, db->options.oid_type)) < 0) return error; if (git_oid_is_zero(oid)) @@ -1564,10 +1719,13 @@ int git_odb_open_wstream( ctx = git__malloc(sizeof(git_hash_ctx)); GIT_ERROR_CHECK_ALLOC(ctx); - if ((error = git_hash_ctx_init(ctx, GIT_HASH_ALGORITHM_SHA1)) < 0 || - (error = hash_header(ctx, size, type)) < 0) + if ((error = git_hash_ctx_init(ctx, git_oid_algorithm(db->options.oid_type))) < 0 || + (error = hash_header(ctx, size, type)) < 0) goto done; +#ifdef GIT_EXPERIMENTAL_SHA256 + (*stream)->oid_type = db->options.oid_type; +#endif (*stream)->hash_ctx = ctx; (*stream)->declared_size = size; (*stream)->received_bytes = 0; @@ -1612,6 +1770,10 @@ int git_odb_stream_finalize_write(git_oid *out, git_odb_stream *stream) git_hash_final(out->id, stream->hash_ctx); +#ifdef GIT_EXPERIMENTAL_SHA256 + out->type = stream->oid_type; +#endif + if (git_odb__freshen(stream->backend->odb, out)) return 0; @@ -1786,10 +1948,11 @@ int git_odb_refresh(struct git_odb *db) int git_odb__error_mismatch(const git_oid *expected, const git_oid *actual) { - char expected_oid[GIT_OID_HEXSZ + 1], actual_oid[GIT_OID_HEXSZ + 1]; + char expected_oid[GIT_OID_MAX_HEXSIZE + 1], + actual_oid[GIT_OID_MAX_HEXSIZE + 1]; - git_oid_tostr(expected_oid, sizeof(expected_oid), expected); - git_oid_tostr(actual_oid, sizeof(actual_oid), actual); + git_oid_tostr(expected_oid, git_oid_hexsize(git_oid_type(expected)) + 1, expected); + git_oid_tostr(actual_oid, git_oid_hexsize(git_oid_type(actual)) + 1, actual); git_error_set(GIT_ERROR_ODB, "object hash mismatch - expected %s but got %s", expected_oid, actual_oid); @@ -1801,7 +1964,7 @@ int git_odb__error_notfound( const char *message, const git_oid *oid, size_t oid_len) { if (oid != NULL) { - char oid_str[GIT_OID_HEXSZ + 1]; + char oid_str[GIT_OID_MAX_HEXSIZE + 1]; git_oid_tostr(oid_str, oid_len+1, oid); git_error_set(GIT_ERROR_ODB, "object not found - %s (%.*s)", message, (int) oid_len, oid_str); @@ -1819,7 +1982,7 @@ static int error_null_oid(int error, const char *message) int git_odb__error_ambiguous(const char *message) { - git_error_set(GIT_ERROR_ODB, "ambiguous SHA1 prefix - %s", message); + git_error_set(GIT_ERROR_ODB, "ambiguous OID prefix - %s", message); return GIT_EAMBIGUOUS; } diff --git a/src/libgit2/odb.h b/src/libgit2/odb.h index 5aa4cc84a..7a712e202 100644 --- a/src/libgit2/odb.h +++ b/src/libgit2/odb.h @@ -10,6 +10,7 @@ #include "common.h" #include "git2/odb.h" +#include "git2/odb_backend.h" #include "git2/oid.h" #include "git2/types.h" #include "git2/sys/commit_graph.h" @@ -46,6 +47,7 @@ struct git_odb_object { struct git_odb { git_refcount rc; git_mutex lock; /* protects backends */ + git_odb_options options; git_vector backends; git_cache own_cache; git_commit_graph *cgraph; @@ -72,7 +74,7 @@ int git_odb__add_default_backends( * Hash a git_rawobj internally. * The `git_rawobj` is supposed to be previously initialized */ -int git_odb__hashobj(git_oid *id, git_rawobj *obj); +int git_odb__hashobj(git_oid *id, git_rawobj *obj, git_oid_t oid_type); /* * Format the object header such as it would appear in the on-disk object @@ -89,14 +91,24 @@ int git_odb__format_object_header(size_t *out_len, char *hdr, size_t hdr_size, g * The fd is never closed, not even on error. It must be opened and closed * by the caller */ -int git_odb__hashfd(git_oid *out, git_file fd, size_t size, git_object_t type); +int git_odb__hashfd( + git_oid *out, + git_file fd, + size_t size, + git_object_t object_type, + git_oid_t oid_type); /* * Hash an open file descriptor applying an array of filters * Acts just like git_odb__hashfd with the addition of filters... */ int git_odb__hashfd_filtered( - git_oid *out, git_file fd, size_t len, git_object_t type, git_filter_list *fl); + git_oid *out, + git_file fd, + size_t len, + git_object_t object_type, + git_oid_t oid_type, + git_filter_list *fl); /* * Hash a `path`, assuming it could be a POSIX symlink: if the path is a @@ -106,7 +118,7 @@ int git_odb__hashfd_filtered( * The hash type for this call is always `GIT_OBJECT_BLOB` because * symlinks may only point to blobs. */ -int git_odb__hashlink(git_oid *out, const char *path); +int git_odb__hashlink(git_oid *out, const char *path, git_oid_t oid_type); /** * Generate a GIT_EMISMATCH error for the ODB. @@ -146,4 +158,31 @@ int git_odb__freshen(git_odb *db, const git_oid *id); /* fully free the object; internal method, DO NOT EXPORT */ void git_odb_object__free(void *object); +/* SHA256 support */ + +int git_odb__new(git_odb **out, const git_odb_options *opts); + +int git_odb__open( + git_odb **out, + const char *objects_dir, + const git_odb_options *opts); + +int git_odb__hash( + git_oid *out, + const void *data, + size_t len, + git_object_t object_type, + git_oid_t oid_type); + +int git_odb__hashfile( + git_oid *out, + const char *path, + git_object_t object_type, + git_oid_t oid_type); + +GIT_EXTERN(int) git_odb__backend_loose( + git_odb_backend **out, + const char *objects_dir, + git_odb_backend_loose_options *opts); + #endif diff --git a/src/libgit2/odb_loose.c b/src/libgit2/odb_loose.c index 463e24fa5..51195d357 100644 --- a/src/libgit2/odb_loose.c +++ b/src/libgit2/odb_loose.c @@ -46,10 +46,8 @@ typedef struct { typedef struct loose_backend { git_odb_backend parent; - int object_zlib_level; /** loose object zlib compression level. */ - int fsync_object_files; /** loose object file fsync flag. */ - mode_t object_file_mode; - mode_t object_dir_mode; + git_odb_backend_loose_options options; + size_t oid_hexsize; size_t objects_dirlen; char objects_dir[GIT_FLEX_ARRAY]; @@ -59,13 +57,19 @@ typedef struct loose_backend { * in order to locate objects matching a short oid. */ typedef struct { + loose_backend *backend; + size_t dir_len; - unsigned char short_oid[GIT_OID_HEXSZ]; /* hex formatted oid to match */ + + /* Hex formatted oid to match (and its length) */ + unsigned char short_oid[GIT_OID_MAX_HEXSIZE]; size_t short_oid_len; - int found; /* number of matching - * objects already found */ - unsigned char res_oid[GIT_OID_HEXSZ]; /* hex formatted oid of - * the object found */ + + /* Number of matching objects found so far */ + int found; + + /* Hex formatted oid of the object found */ + unsigned char res_oid[GIT_OID_MAX_HEXSIZE]; } loose_locate_object_state; @@ -78,20 +82,17 @@ typedef struct { static int object_file_name( git_str *name, const loose_backend *be, const git_oid *id) { - size_t alloclen; - - /* expand length for object root + 40 hex sha1 chars + 2 * '/' + '\0' */ - GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, be->objects_dirlen, GIT_OID_HEXSZ); - GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, alloclen, 3); - if (git_str_grow(name, alloclen) < 0) - return -1; + /* append loose object filename: aa/aaa... (41 bytes plus NUL) */ + size_t path_size = be->oid_hexsize + 1; git_str_set(name, be->objects_dir, be->objects_dirlen); git_fs_path_to_dir(name); - /* loose object filename: aa/aaa... (41 bytes) */ + if (git_str_grow_by(name, path_size + 1) < 0) + return -1; + git_oid_pathfmt(name->ptr + name->size, id); - name->size += GIT_OID_HEXSZ + 1; + name->size += path_size; name->ptr[name->size] = '\0'; return 0; @@ -100,7 +101,9 @@ static int object_file_name( static int object_mkdir(const git_str *name, const loose_backend *be) { return git_futils_mkdir_relative( - name->ptr + be->objects_dirlen, be->objects_dir, be->object_dir_mode, + name->ptr + be->objects_dirlen, + be->objects_dir, + be->options.dir_mode, GIT_MKDIR_PATH | GIT_MKDIR_SKIP_LAST | GIT_MKDIR_VERIFY_DIR, NULL); } @@ -461,8 +464,9 @@ static int locate_object( /* Explore an entry of a directory and see if it matches a short oid */ static int fn_locate_object_short_oid(void *state, git_str *pathbuf) { loose_locate_object_state *sstate = (loose_locate_object_state *)state; + size_t hex_size = sstate->backend->oid_hexsize; - if (git_str_len(pathbuf) - sstate->dir_len != GIT_OID_HEXSZ - 2) { + if (git_str_len(pathbuf) - sstate->dir_len != hex_size - 2) { /* Entry cannot be an object. Continue to next entry */ return 0; } @@ -477,7 +481,9 @@ static int fn_locate_object_short_oid(void *state, git_str *pathbuf) { if (!sstate->found) { sstate->res_oid[0] = sstate->short_oid[0]; sstate->res_oid[1] = sstate->short_oid[1]; - memcpy(sstate->res_oid+2, pathbuf->ptr+sstate->dir_len, GIT_OID_HEXSZ-2); + memcpy(sstate->res_oid + 2, + pathbuf->ptr+sstate->dir_len, + hex_size - 2); } sstate->found++; } @@ -503,7 +509,7 @@ static int locate_object_short_oid( int error; /* prealloc memory for OBJ_DIR/xx/xx..38x..xx */ - GIT_ERROR_CHECK_ALLOC_ADD(&alloc_len, dir_len, GIT_OID_HEXSZ); + GIT_ERROR_CHECK_ALLOC_ADD(&alloc_len, dir_len, backend->oid_hexsize); GIT_ERROR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 3); if (git_str_grow(object_location, alloc_len) < 0) return -1; @@ -527,6 +533,7 @@ static int locate_object_short_oid( return git_odb__error_notfound("no matching loose object for prefix", short_oid, len); + state.backend = backend; state.dir_len = git_str_len(object_location); state.short_oid_len = len; state.found = 0; @@ -545,12 +552,12 @@ static int locate_object_short_oid( return git_odb__error_ambiguous("multiple matches in loose objects"); /* Convert obtained hex formatted oid to raw */ - error = git_oid_fromstr(res_oid, (char *)state.res_oid); + error = git_oid__fromstr(res_oid, (char *)state.res_oid, backend->options.oid_type); if (error) return error; /* Update the location according to the oid obtained */ - GIT_ERROR_CHECK_ALLOC_ADD(&alloc_len, dir_len, GIT_OID_HEXSZ); + GIT_ERROR_CHECK_ALLOC_ADD(&alloc_len, dir_len, backend->oid_hexsize); GIT_ERROR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 2); git_str_truncate(object_location, dir_len); @@ -559,20 +566,12 @@ static int locate_object_short_oid( git_oid_pathfmt(object_location->ptr + dir_len, res_oid); - object_location->size += GIT_OID_HEXSZ + 1; + object_location->size += backend->oid_hexsize + 1; object_location->ptr[object_location->size] = '\0'; return 0; } - - - - - - - - /*********************************************************** * * LOOSE BACKEND PUBLIC API @@ -595,7 +594,7 @@ static int loose_backend__read_header(size_t *len_p, git_object_t *type_p, git_o if (locate_object(&object_path, (loose_backend *)backend, oid) < 0) { error = git_odb__error_notfound("no matching loose object", - oid, GIT_OID_HEXSZ); + oid, ((struct loose_backend *)backend)->oid_hexsize); } else if ((error = read_header_loose(&raw, &object_path)) == 0) { *len_p = raw.len; *type_p = raw.type; @@ -617,7 +616,7 @@ static int loose_backend__read(void **buffer_p, size_t *len_p, git_object_t *typ if (locate_object(&object_path, (loose_backend *)backend, oid) < 0) { error = git_odb__error_notfound("no matching loose object", - oid, GIT_OID_HEXSZ); + oid, ((struct loose_backend *)backend)->oid_hexsize); } else if ((error = read_loose(&raw, &object_path)) == 0) { *buffer_p = raw.data; *len_p = raw.len; @@ -634,17 +633,19 @@ static int loose_backend__read_prefix( void **buffer_p, size_t *len_p, git_object_t *type_p, - git_odb_backend *backend, + git_odb_backend *_backend, const git_oid *short_oid, size_t len) { + struct loose_backend *backend = (struct loose_backend *)_backend; int error = 0; - GIT_ASSERT_ARG(len >= GIT_OID_MINPREFIXLEN && len <= GIT_OID_HEXSZ); + GIT_ASSERT_ARG(len >= GIT_OID_MINPREFIXLEN && + len <= backend->oid_hexsize); - if (len == GIT_OID_HEXSZ) { + if (len == backend->oid_hexsize) { /* We can fall back to regular read method */ - error = loose_backend__read(buffer_p, len_p, type_p, backend, short_oid); + error = loose_backend__read(buffer_p, len_p, type_p, _backend, short_oid); if (!error) git_oid_cpy(out_oid, short_oid); } else { @@ -703,15 +704,18 @@ static int loose_backend__exists_prefix( } struct foreach_state { + struct loose_backend *backend; size_t dir_len; git_odb_foreach_cb cb; void *data; }; -GIT_INLINE(int) filename_to_oid(git_oid *oid, const char *ptr) +GIT_INLINE(int) filename_to_oid(struct loose_backend *backend, git_oid *oid, const char *ptr) { - int v, i = 0; - if (strlen(ptr) != GIT_OID_HEXSZ+1) + int v; + size_t i = 0; + + if (strlen(ptr) != backend->oid_hexsize + 1) return -1; if (ptr[2] != '/') { @@ -725,7 +729,7 @@ GIT_INLINE(int) filename_to_oid(git_oid *oid, const char *ptr) oid->id[0] = (unsigned char) v; ptr += 3; - for (i = 0; i < 38; i += 2) { + for (i = 0; i < backend->oid_hexsize - 2; i += 2) { v = (git__fromhex(ptr[i]) << 4) | git__fromhex(ptr[i + 1]); if (v < 0) return -1; @@ -733,6 +737,10 @@ GIT_INLINE(int) filename_to_oid(git_oid *oid, const char *ptr) oid->id[1 + i/2] = (unsigned char) v; } +#ifdef GIT_EXPERIMENTAL_SHA256 + oid->type = backend->options.oid_type; +#endif + return 0; } @@ -741,7 +749,7 @@ static int foreach_object_dir_cb(void *_state, git_str *path) git_oid oid; struct foreach_state *state = (struct foreach_state *) _state; - if (filename_to_oid(&oid, path->ptr + state->dir_len) < 0) + if (filename_to_oid(state->backend, &oid, path->ptr + state->dir_len) < 0) return 0; return git_error_set_after_callback_function( @@ -778,6 +786,7 @@ static int loose_backend__foreach(git_odb_backend *_backend, git_odb_foreach_cb return -1; memset(&state, 0, sizeof(state)); + state.backend = backend; state.cb = cb; state.data = data; state.dir_len = git_str_len(&buf); @@ -825,9 +834,10 @@ static void loose_backend__writestream_free(git_odb_stream *_stream) static int filebuf_flags(loose_backend *backend) { int flags = GIT_FILEBUF_TEMPORARY | - (backend->object_zlib_level << GIT_FILEBUF_DEFLATE_SHIFT); + (backend->options.compression_level << GIT_FILEBUF_DEFLATE_SHIFT); - if (backend->fsync_object_files || git_repository__fsync_gitdir) + if ((backend->options.flags & GIT_ODB_BACKEND_LOOSE_FSYNC) || + git_repository__fsync_gitdir) flags |= GIT_FILEBUF_FSYNC; return flags; @@ -863,7 +873,7 @@ static int loose_backend__writestream(git_odb_stream **stream_out, git_odb_backe if (git_str_joinpath(&tmp_path, backend->objects_dir, "tmp_object") < 0 || git_filebuf_open(&stream->fbuf, tmp_path.ptr, filebuf_flags(backend), - backend->object_file_mode) < 0 || + backend->options.file_mode) < 0 || stream->stream.write((git_odb_stream *)stream, hdr, hdrlen) < 0) { git_filebuf_cleanup(&stream->fbuf); @@ -997,6 +1007,7 @@ static int loose_backend__readstream( loose_readstream *stream = NULL; git_hash_ctx *hash_ctx = NULL; git_str object_path = GIT_STR_INIT; + git_hash_algorithm_t algorithm; obj_hdr hdr; int error = 0; @@ -1013,7 +1024,7 @@ static int loose_backend__readstream( if (locate_object(&object_path, backend, oid) < 0) { error = git_odb__error_notfound("no matching loose object", - oid, GIT_OID_HEXSZ); + oid, backend->oid_hexsize); goto done; } @@ -1023,9 +1034,11 @@ static int loose_backend__readstream( hash_ctx = git__malloc(sizeof(git_hash_ctx)); GIT_ERROR_CHECK_ALLOC(hash_ctx); - if ((error = git_hash_ctx_init(hash_ctx, GIT_HASH_ALGORITHM_SHA1)) < 0 || - (error = git_futils_mmap_ro_file(&stream->map, object_path.ptr)) < 0 || - (error = git_zstream_init(&stream->zstream, GIT_ZSTREAM_INFLATE)) < 0) + algorithm = git_oid_algorithm(backend->options.oid_type); + + if ((error = git_hash_ctx_init(hash_ctx, algorithm)) < 0 || + (error = git_futils_mmap_ro_file(&stream->map, object_path.ptr)) < 0 || + (error = git_zstream_init(&stream->zstream, GIT_ZSTREAM_INFLATE)) < 0) goto done; /* check for a packlike loose object */ @@ -1081,7 +1094,7 @@ static int loose_backend__write(git_odb_backend *_backend, const git_oid *oid, c if (git_str_joinpath(&final_path, backend->objects_dir, "tmp_object") < 0 || git_filebuf_open(&fbuf, final_path.ptr, filebuf_flags(backend), - backend->object_file_mode) < 0) + backend->options.file_mode) < 0) { error = -1; goto cleanup; @@ -1124,13 +1137,34 @@ static void loose_backend__free(git_odb_backend *_backend) git__free(_backend); } -int git_odb_backend_loose( +static void normalize_options( + git_odb_backend_loose_options *opts, + const git_odb_backend_loose_options *given_opts) +{ + git_odb_backend_loose_options init = GIT_ODB_BACKEND_LOOSE_OPTIONS_INIT; + + if (given_opts) + memcpy(opts, given_opts, sizeof(git_odb_backend_loose_options)); + else + memcpy(opts, &init, sizeof(git_odb_backend_loose_options)); + + if (opts->compression_level < 0) + opts->compression_level = Z_BEST_SPEED; + + if (opts->dir_mode == 0) + opts->dir_mode = GIT_OBJECT_DIR_MODE; + + if (opts->file_mode == 0) + opts->file_mode = GIT_OBJECT_FILE_MODE; + + if (opts->oid_type == 0) + opts->oid_type = GIT_OID_DEFAULT; +} + +int git_odb__backend_loose( git_odb_backend **backend_out, const char *objects_dir, - int compression_level, - int do_fsync, - unsigned int dir_mode, - unsigned int file_mode) + git_odb_backend_loose_options *opts) { loose_backend *backend; size_t objects_dirlen, alloclen; @@ -1148,22 +1182,12 @@ int git_odb_backend_loose( backend->parent.version = GIT_ODB_BACKEND_VERSION; backend->objects_dirlen = objects_dirlen; memcpy(backend->objects_dir, objects_dir, objects_dirlen); + if (backend->objects_dir[backend->objects_dirlen - 1] != '/') backend->objects_dir[backend->objects_dirlen++] = '/'; - if (compression_level < 0) - compression_level = Z_BEST_SPEED; - - if (dir_mode == 0) - dir_mode = GIT_OBJECT_DIR_MODE; - - if (file_mode == 0) - file_mode = GIT_OBJECT_FILE_MODE; - - backend->object_zlib_level = compression_level; - backend->fsync_object_files = do_fsync; - backend->object_dir_mode = dir_mode; - backend->object_file_mode = file_mode; + normalize_options(&backend->options, opts); + backend->oid_hexsize = git_oid_hexsize(backend->options.oid_type); backend->parent.read = &loose_backend__read; backend->parent.write = &loose_backend__write; @@ -1180,3 +1204,37 @@ int git_odb_backend_loose( *backend_out = (git_odb_backend *)backend; return 0; } + + +#ifdef GIT_EXPERIMENTAL_SHA256 +int git_odb_backend_loose( + git_odb_backend **backend_out, + const char *objects_dir, + git_odb_backend_loose_options *opts) +{ + return git_odb__backend_loose(backend_out, objects_dir, opts); +} +#else +int git_odb_backend_loose( + git_odb_backend **backend_out, + const char *objects_dir, + int compression_level, + int do_fsync, + unsigned int dir_mode, + unsigned int file_mode) +{ + git_odb_backend_loose_flag_t flags = 0; + git_odb_backend_loose_options opts = GIT_ODB_BACKEND_LOOSE_OPTIONS_INIT; + + if (do_fsync) + flags |= GIT_ODB_BACKEND_LOOSE_FSYNC; + + opts.flags = flags; + opts.compression_level = compression_level; + opts.dir_mode = dir_mode; + opts.file_mode = file_mode; + opts.oid_type = GIT_OID_DEFAULT; + + return git_odb__backend_loose(backend_out, objects_dir, &opts); +} +#endif diff --git a/src/libgit2/odb_pack.c b/src/libgit2/odb_pack.c index 818cc6125..1b1d122b0 100644 --- a/src/libgit2/odb_pack.c +++ b/src/libgit2/odb_pack.c @@ -26,6 +26,7 @@ struct pack_backend { git_odb_backend parent; + git_odb_backend_pack_options opts; git_midx_file *midx; git_vector midx_packs; git_vector packs; @@ -95,24 +96,24 @@ struct pack_writepack { * -------------------------------------------------- * * # pack_backend__exists / pack_backend__exists_prefix - * | Check if the given SHA1 oid (or a SHA1 oid prefix) exists in any of the + * | Check if the given oid (or an oid prefix) exists in any of the * | packs that have been loaded for our ODB. * | * |-# pack_entry_find / pack_entry_find_prefix - * | If there is a multi-pack-index present, search the SHA1 oid in that + * | If there is a multi-pack-index present, search the oid in that * | index first. If it is not found there, iterate through all the unindexed * | packs that have been preloaded (starting by the pack where the latest * | object was found) to try to find the OID in one of them. * | * |-# git_midx_entry_find - * | Search for the SHA1 oid in the multi-pack-index. See + * | Search for the oid in the multi-pack-index. See * | * | for specifics on the multi-pack-index format and how do we find * | entries in it. * | * |-# git_pack_entry_find - * | Check the index of an individual unindexed pack to see if the SHA1 - * | OID can be found. If we can find the offset to that SHA1 inside of the + * | Check the index of an individual unindexed pack to see if the + * | OID can be found. If we can find the offset to that inside of the * | index, that means the object is contained inside of the packfile and * | we can stop searching. Before returning, we verify that the * | packfile behind the index we are searching still exists on disk. @@ -141,13 +142,13 @@ struct pack_writepack { * -------------------------------------------------- * * # pack_backend__read / pack_backend__read_prefix - * | Check if the given SHA1 oid (or a SHA1 oid prefix) exists in any of the + * | Check if the given oid (or an oid prefix) exists in any of the * | packs that have been loaded for our ODB. If it does, open the packfile and * | read from it. * | * |-# git_packfile_unpack * Armed with a packfile and the offset within it, we can finally unpack - * the object pointed at by the SHA1 oid. This involves mmapping part of + * the object pointed at by the oid. This involves mmapping part of * the `.pack` file, and uncompressing the object within it (if it is * stored in the undelfitied representation), or finding a base object and * applying some deltas to its uncompressed representation (if it is stored @@ -177,7 +178,7 @@ static int pack_entry_find(struct git_pack_entry *e, * a prefix of an identifier. * Sets GIT_EAMBIGUOUS if short oid is ambiguous. * This method assumes that len is between - * GIT_OID_MINPREFIXLEN and GIT_OID_HEXSZ. + * GIT_OID_MINPREFIXLEN and the hexsize for the hash type. */ static int pack_entry_find_prefix( struct git_pack_entry *e, @@ -251,7 +252,7 @@ static int packfile_load__cb(void *data, git_str *path) if (git_vector_search2(NULL, &backend->packs, packfile_byname_search_cmp, &index_prefix) == 0) return 0; - error = git_mwindow_get_pack(&pack, path->ptr); + error = git_mwindow_get_pack(&pack, path->ptr, backend->opts.oid_type); /* ignore missing .pack file as git does */ if (error == GIT_ENOTFOUND) { @@ -270,33 +271,34 @@ static int pack_entry_find(struct git_pack_entry *e, struct pack_backend *backen { struct git_pack_file *last_found = backend->last_found, *p; git_midx_entry midx_entry; + size_t oid_hexsize = git_oid_hexsize(backend->opts.oid_type); size_t i; if (backend->midx && - git_midx_entry_find(&midx_entry, backend->midx, oid, GIT_OID_HEXSZ) == 0 && + git_midx_entry_find(&midx_entry, backend->midx, oid, oid_hexsize) == 0 && midx_entry.pack_index < git_vector_length(&backend->midx_packs)) { e->offset = midx_entry.offset; - git_oid_cpy(&e->sha1, &midx_entry.sha1); + git_oid_cpy(&e->id, &midx_entry.sha1); e->p = git_vector_get(&backend->midx_packs, midx_entry.pack_index); return 0; } if (last_found && - git_pack_entry_find(e, last_found, oid, GIT_OID_HEXSZ) == 0) + git_pack_entry_find(e, last_found, oid, oid_hexsize) == 0) return 0; git_vector_foreach(&backend->packs, i, p) { if (p == last_found) continue; - if (git_pack_entry_find(e, p, oid, GIT_OID_HEXSZ) == 0) { + if (git_pack_entry_find(e, p, oid, oid_hexsize) == 0) { backend->last_found = p; return 0; } } return git_odb__error_notfound( - "failed to find pack entry", oid, GIT_OID_HEXSZ); + "failed to find pack entry", oid, oid_hexsize); } static int pack_entry_find_prefix( @@ -307,7 +309,7 @@ static int pack_entry_find_prefix( { int error; size_t i; - git_oid found_full_oid = {{0}}; + git_oid found_full_oid = GIT_OID_SHA1_ZERO; bool found = false; struct git_pack_file *last_found = backend->last_found, *p; git_midx_entry midx_entry; @@ -318,9 +320,9 @@ static int pack_entry_find_prefix( return error; if (!error && midx_entry.pack_index < git_vector_length(&backend->midx_packs)) { e->offset = midx_entry.offset; - git_oid_cpy(&e->sha1, &midx_entry.sha1); + git_oid_cpy(&e->id, &midx_entry.sha1); e->p = git_vector_get(&backend->midx_packs, midx_entry.pack_index); - git_oid_cpy(&found_full_oid, &e->sha1); + git_oid_cpy(&found_full_oid, &e->id); found = true; } } @@ -330,9 +332,9 @@ static int pack_entry_find_prefix( if (error == GIT_EAMBIGUOUS) return error; if (!error) { - if (found && git_oid_cmp(&e->sha1, &found_full_oid)) + if (found && git_oid_cmp(&e->id, &found_full_oid)) return git_odb__error_ambiguous("found multiple pack entries"); - git_oid_cpy(&found_full_oid, &e->sha1); + git_oid_cpy(&found_full_oid, &e->id); found = true; } } @@ -345,9 +347,9 @@ static int pack_entry_find_prefix( if (error == GIT_EAMBIGUOUS) return error; if (!error) { - if (found && git_oid_cmp(&e->sha1, &found_full_oid)) + if (found && git_oid_cmp(&e->id, &found_full_oid)) return git_odb__error_ambiguous("found multiple pack entries"); - git_oid_cpy(&found_full_oid, &e->sha1); + git_oid_cpy(&found_full_oid, &e->id); found = true; backend->last_found = p; } @@ -425,7 +427,10 @@ static int process_multi_pack_index_pack( } /* Pack was not found. Allocate a new one. */ - error = git_mwindow_get_pack(&pack, git_str_cstr(&pack_path)); + error = git_mwindow_get_pack( + &pack, + git_str_cstr(&pack_path), + backend->opts.oid_type); git_str_dispose(&pack_path); if (error < 0) return error; @@ -596,32 +601,33 @@ static int pack_backend__read_prefix( void **buffer_p, size_t *len_p, git_object_t *type_p, - git_odb_backend *backend, + git_odb_backend *_backend, const git_oid *short_oid, size_t len) { + struct pack_backend *backend = (struct pack_backend *)_backend; int error = 0; if (len < GIT_OID_MINPREFIXLEN) error = git_odb__error_ambiguous("prefix length too short"); - else if (len >= GIT_OID_HEXSZ) { + else if (len >= git_oid_hexsize(backend->opts.oid_type)) { /* We can fall back to regular read method */ - error = pack_backend__read(buffer_p, len_p, type_p, backend, short_oid); + error = pack_backend__read(buffer_p, len_p, type_p, _backend, short_oid); if (!error) git_oid_cpy(out_oid, short_oid); } else { struct git_pack_entry e; git_rawobj raw = {NULL}; - if ((error = pack_entry_find_prefix( - &e, (struct pack_backend *)backend, short_oid, len)) == 0 && - (error = git_packfile_unpack(&raw, e.p, &e.offset)) == 0) + if ((error = pack_entry_find_prefix(&e, + backend, short_oid, len)) == 0 && + (error = git_packfile_unpack(&raw, e.p, &e.offset)) == 0) { *buffer_p = raw.data; *len_p = raw.len; *type_p = raw.type; - git_oid_cpy(out_oid, &e.sha1); + git_oid_cpy(out_oid, &e.id); } } @@ -642,7 +648,7 @@ static int pack_backend__exists_prefix( struct git_pack_entry e = {0}; error = pack_entry_find_prefix(&e, pb, short_id, len); - git_oid_cpy(out, &e.sha1); + git_oid_cpy(out, &e.id); return error; } @@ -712,6 +718,7 @@ static int pack_backend__writepack(struct git_odb_writepack **out, git_indexer_options opts = GIT_INDEXER_OPTIONS_INIT; struct pack_backend *backend; struct pack_writepack *writepack; + int error; GIT_ASSERT_ARG(out); GIT_ASSERT_ARG(_backend); @@ -726,11 +733,20 @@ static int pack_backend__writepack(struct git_odb_writepack **out, writepack = git__calloc(1, sizeof(struct pack_writepack)); GIT_ERROR_CHECK_ALLOC(writepack); - if (git_indexer_new(&writepack->indexer, - backend->pack_folder, 0, odb, &opts) < 0) { - git__free(writepack); +#ifdef GIT_EXPERIMENTAL_SHA256 + opts.odb = odb; + + error = git_indexer_new(&writepack->indexer, + backend->pack_folder, + backend->opts.oid_type, + &opts); +#else + error = git_indexer_new(&writepack->indexer, + backend->pack_folder, 0, odb, &opts); +#endif + + if (error < 0) return -1; - } writepack->parent.backend = _backend; writepack->parent.append = pack_backend__writepack_append; @@ -840,7 +856,10 @@ static void pack_backend__free(git_odb_backend *_backend) git__free(backend); } -static int pack_backend__alloc(struct pack_backend **out, size_t initial_size) +static int pack_backend__alloc( + struct pack_backend **out, + size_t initial_size, + const git_odb_backend_pack_options *opts) { struct pack_backend *backend = git__calloc(1, sizeof(struct pack_backend)); GIT_ERROR_CHECK_ALLOC(backend); @@ -849,12 +868,19 @@ static int pack_backend__alloc(struct pack_backend **out, size_t initial_size) git__free(backend); return -1; } + if (git_vector_init(&backend->packs, initial_size, packfile_sort__cb) < 0) { git_vector_free(&backend->midx_packs); git__free(backend); return -1; } + if (opts) + memcpy(&backend->opts, opts, sizeof(git_odb_backend_pack_options)); + + if (!backend->opts.oid_type) + backend->opts.oid_type = GIT_OID_DEFAULT; + backend->parent.version = GIT_ODB_BACKEND_VERSION; backend->parent.read = &pack_backend__read; @@ -873,17 +899,31 @@ static int pack_backend__alloc(struct pack_backend **out, size_t initial_size) return 0; } -int git_odb_backend_one_pack(git_odb_backend **backend_out, const char *idx) +#ifdef GIT_EXPERIMENTAL_SHA256 +int git_odb_backend_one_pack( + git_odb_backend **backend_out, + const char *idx, + const git_odb_backend_pack_options *opts) +#else +int git_odb_backend_one_pack( + git_odb_backend **backend_out, + const char *idx) +#endif { struct pack_backend *backend = NULL; struct git_pack_file *packfile = NULL; - if (pack_backend__alloc(&backend, 1) < 0) +#ifndef GIT_EXPERIMENTAL_SHA256 + git_odb_backend_pack_options *opts = NULL; +#endif + + git_oid_t oid_type = opts ? opts->oid_type : 0; + + if (pack_backend__alloc(&backend, 1, opts) < 0) return -1; - if (git_mwindow_get_pack(&packfile, idx) < 0 || - git_vector_insert(&backend->packs, packfile) < 0) - { + if (git_mwindow_get_pack(&packfile, idx, oid_type) < 0 || + git_vector_insert(&backend->packs, packfile) < 0) { pack_backend__free((git_odb_backend *)backend); return -1; } @@ -892,18 +932,30 @@ int git_odb_backend_one_pack(git_odb_backend **backend_out, const char *idx) return 0; } -int git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir) +#ifdef GIT_EXPERIMENTAL_SHA256 +int git_odb_backend_pack( + git_odb_backend **backend_out, + const char *objects_dir, + const git_odb_backend_pack_options *opts) +#else +int git_odb_backend_pack( + git_odb_backend **backend_out, + const char *objects_dir) +#endif { int error = 0; struct pack_backend *backend = NULL; git_str path = GIT_STR_INIT; - if (pack_backend__alloc(&backend, 8) < 0) +#ifndef GIT_EXPERIMENTAL_SHA256 + git_odb_backend_pack_options *opts = NULL; +#endif + + if (pack_backend__alloc(&backend, 8, opts) < 0) return -1; if (!(error = git_str_joinpath(&path, objects_dir, "pack")) && - git_fs_path_isdir(git_str_cstr(&path))) - { + git_fs_path_isdir(git_str_cstr(&path))) { backend->pack_folder = git_str_detach(&path); error = pack_backend__refresh((git_odb_backend *)backend); } diff --git a/src/libgit2/oid.c b/src/libgit2/oid.c index fb92174ab..6cc21641d 100644 --- a/src/libgit2/oid.c +++ b/src/libgit2/oid.c @@ -14,13 +14,13 @@ #include const git_oid git_oid__empty_blob_sha1 = - {{ 0xe6, 0x9d, 0xe2, 0x9b, 0xb2, 0xd1, 0xd6, 0x43, 0x4b, 0x8b, - 0x29, 0xae, 0x77, 0x5a, 0xd8, 0xc2, 0xe4, 0x8c, 0x53, 0x91 }}; + GIT_OID_INIT(GIT_OID_SHA1, + { 0xe6, 0x9d, 0xe2, 0x9b, 0xb2, 0xd1, 0xd6, 0x43, 0x4b, 0x8b, + 0x29, 0xae, 0x77, 0x5a, 0xd8, 0xc2, 0xe4, 0x8c, 0x53, 0x91 }); const git_oid git_oid__empty_tree_sha1 = - {{ 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60, - 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04 }}; - -static char to_hex[] = "0123456789abcdef"; + GIT_OID_INIT(GIT_OID_SHA1, + { 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60, + 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04 }); static int oid_error_invalid(const char *msg) { @@ -28,21 +28,31 @@ static int oid_error_invalid(const char *msg) return -1; } -int git_oid_fromstrn(git_oid *out, const char *str, size_t length) +int git_oid__fromstrn( + git_oid *out, + const char *str, + size_t length, + git_oid_t type) { - size_t p; + size_t size, p; int v; GIT_ASSERT_ARG(out); GIT_ASSERT_ARG(str); + if (!(size = git_oid_size(type))) + return oid_error_invalid("unknown type"); + if (!length) return oid_error_invalid("too short"); - if (length > GIT_OID_HEXSZ) + if (length > git_oid_hexsize(type)) return oid_error_invalid("too long"); - memset(out->id, 0, GIT_OID_RAWSZ); +#ifdef GIT_EXPERIMENTAL_SHA256 + out->type = type; +#endif + memset(out->id, 0, size); for (p = 0; p < length; p++) { v = git__fromhex(str[p]); @@ -55,87 +65,128 @@ int git_oid_fromstrn(git_oid *out, const char *str, size_t length) return 0; } +int git_oid__fromstrp(git_oid *out, const char *str, git_oid_t type) +{ + return git_oid__fromstrn(out, str, strlen(str), type); +} + +int git_oid__fromstr(git_oid *out, const char *str, git_oid_t type) +{ + return git_oid__fromstrn(out, str, git_oid_hexsize(type), type); +} + +#ifdef GIT_EXPERIMENTAL_SHA256 +int git_oid_fromstrn( + git_oid *out, + const char *str, + size_t length, + git_oid_t type) +{ + return git_oid__fromstrn(out, str, length, type); +} + +int git_oid_fromstrp(git_oid *out, const char *str, git_oid_t type) +{ + return git_oid_fromstrn(out, str, strlen(str), type); +} + +int git_oid_fromstr(git_oid *out, const char *str, git_oid_t type) +{ + return git_oid_fromstrn(out, str, git_oid_hexsize(type), type); +} +#else +int git_oid_fromstrn( + git_oid *out, + const char *str, + size_t length) +{ + return git_oid__fromstrn(out, str, length, GIT_OID_SHA1); +} + int git_oid_fromstrp(git_oid *out, const char *str) { - return git_oid_fromstrn(out, str, strlen(str)); + return git_oid__fromstrn(out, str, strlen(str), GIT_OID_SHA1); } int git_oid_fromstr(git_oid *out, const char *str) { - return git_oid_fromstrn(out, str, GIT_OID_HEXSZ); -} - -GIT_INLINE(char) *fmt_one(char *str, unsigned int val) -{ - *str++ = to_hex[val >> 4]; - *str++ = to_hex[val & 0xf]; - return str; + return git_oid__fromstrn(out, str, GIT_OID_SHA1_HEXSIZE, GIT_OID_SHA1); } +#endif int git_oid_nfmt(char *str, size_t n, const git_oid *oid) { - size_t i, max_i; + size_t hex_size; if (!oid) { memset(str, 0, n); return 0; } - if (n > GIT_OID_HEXSZ) { - memset(&str[GIT_OID_HEXSZ], 0, n - GIT_OID_HEXSZ); - n = GIT_OID_HEXSZ; + + if (!(hex_size = git_oid_hexsize(git_oid_type(oid)))) + return oid_error_invalid("unknown type"); + + if (n > hex_size) { + memset(&str[hex_size], 0, n - hex_size); + n = hex_size; } - max_i = n / 2; - - for (i = 0; i < max_i; i++) - str = fmt_one(str, oid->id[i]); - - if (n & 1) - *str++ = to_hex[oid->id[i] >> 4]; - + git_oid_fmt_substr(str, oid, 0, n); return 0; } int git_oid_fmt(char *str, const git_oid *oid) { - return git_oid_nfmt(str, GIT_OID_HEXSZ, oid); + return git_oid_nfmt(str, git_oid_hexsize(git_oid_type(oid)), oid); } int git_oid_pathfmt(char *str, const git_oid *oid) { - size_t i; + size_t hex_size; - str = fmt_one(str, oid->id[0]); - *str++ = '/'; - for (i = 1; i < sizeof(oid->id); i++) - str = fmt_one(str, oid->id[i]); + if (!(hex_size = git_oid_hexsize(git_oid_type(oid)))) + return oid_error_invalid("unknown type"); + git_oid_fmt_substr(str, oid, 0, 2); + str[2] = '/'; + git_oid_fmt_substr(&str[3], oid, 2, (hex_size - 2)); return 0; } char *git_oid_tostr_s(const git_oid *oid) { char *str = GIT_THREADSTATE->oid_fmt; - git_oid_nfmt(str, GIT_OID_HEXSZ + 1, oid); + git_oid_nfmt(str, git_oid_hexsize(git_oid_type(oid)) + 1, oid); return str; } char *git_oid_allocfmt(const git_oid *oid) { - char *str = git__malloc(GIT_OID_HEXSZ + 1); - if (!str) + size_t hex_size = git_oid_hexsize(git_oid_type(oid)); + char *str = git__malloc(hex_size + 1); + + if (!hex_size || !str) return NULL; - git_oid_nfmt(str, GIT_OID_HEXSZ + 1, oid); + + if (git_oid_nfmt(str, hex_size + 1, oid) < 0) { + git__free(str); + return NULL; + } + return str; } char *git_oid_tostr(char *out, size_t n, const git_oid *oid) { + size_t hex_size; + if (!out || n == 0) return ""; - if (n > GIT_OID_HEXSZ + 1) - n = GIT_OID_HEXSZ + 1; + hex_size = oid ? git_oid_hexsize(git_oid_type(oid)) : 0; + + if (n > hex_size + 1) + n = hex_size + 1; git_oid_nfmt(out, n - 1, oid); /* allow room for terminating NUL */ out[n - 1] = '\0'; @@ -143,51 +194,44 @@ char *git_oid_tostr(char *out, size_t n, const git_oid *oid) return out; } -int git_oid__parse( - git_oid *oid, const char **buffer_out, - const char *buffer_end, const char *header) +int git_oid__fromraw(git_oid *out, const unsigned char *raw, git_oid_t type) { - const size_t sha_len = GIT_OID_HEXSZ; - const size_t header_len = strlen(header); + size_t size; - const char *buffer = *buffer_out; - - if (buffer + (header_len + sha_len + 1) > buffer_end) - return -1; - - if (memcmp(buffer, header, header_len) != 0) - return -1; - - if (buffer[header_len + sha_len] != '\n') - return -1; - - if (git_oid_fromstr(oid, buffer + header_len) < 0) - return -1; - - *buffer_out = buffer + (header_len + sha_len + 1); + if (!(size = git_oid_size(type))) + return oid_error_invalid("unknown type"); +#ifdef GIT_EXPERIMENTAL_SHA256 + out->type = type; +#endif + memcpy(out->id, raw, size); return 0; } -void git_oid__writebuf(git_str *buf, const char *header, const git_oid *oid) +#ifdef GIT_EXPERIMENTAL_SHA256 +int git_oid_fromraw(git_oid *out, const unsigned char *raw, git_oid_t type) { - char hex_oid[GIT_OID_HEXSZ]; - - git_oid_fmt(hex_oid, oid); - git_str_puts(buf, header); - git_str_put(buf, hex_oid, GIT_OID_HEXSZ); - git_str_putc(buf, '\n'); + return git_oid__fromraw(out, raw, type); } - +#else int git_oid_fromraw(git_oid *out, const unsigned char *raw) { - memcpy(out->id, raw, sizeof(out->id)); - return 0; + return git_oid__fromraw(out, raw, GIT_OID_SHA1); } +#endif int git_oid_cpy(git_oid *out, const git_oid *src) { - return git_oid_raw_cpy(out->id, src->id); + size_t size; + + if (!(size = git_oid_size(git_oid_type(src)))) + return oid_error_invalid("unknown type"); + +#ifdef GIT_EXPERIMENTAL_SHA256 + out->type = src->type; +#endif + + return git_oid_raw_cpy(out->id, src->id, size); } int git_oid_cmp(const git_oid *a, const git_oid *b) @@ -202,6 +246,11 @@ int git_oid_equal(const git_oid *a, const git_oid *b) int git_oid_ncmp(const git_oid *oid_a, const git_oid *oid_b, size_t len) { +#ifdef GIT_EXPERIMENTAL_SHA256 + if (oid_a->type != oid_b->type) + return oid_a->type - oid_b->type; +#endif + return git_oid_raw_ncmp(oid_a->id, oid_b->id, len); } @@ -209,9 +258,10 @@ int git_oid_strcmp(const git_oid *oid_a, const char *str) { const unsigned char *a; unsigned char strval; + long size = (long)git_oid_size(git_oid_type(oid_a)); int hexval; - for (a = oid_a->id; *str && (a - oid_a->id) < GIT_OID_RAWSZ; ++a) { + for (a = oid_a->id; *str && (a - oid_a->id) < size; ++a) { if ((hexval = git__fromhex(*str++)) < 0) return -1; strval = (unsigned char)(hexval << 4); @@ -235,8 +285,16 @@ int git_oid_streq(const git_oid *oid_a, const char *str) int git_oid_is_zero(const git_oid *oid_a) { const unsigned char *a = oid_a->id; - unsigned int i; - for (i = 0; i < GIT_OID_RAWSZ; ++i, ++a) + size_t size = git_oid_size(git_oid_type(oid_a)), i; + +#ifdef GIT_EXPERIMENTAL_SHA256 + if (!oid_a->type) + return 1; + else if (!size) + return 0; +#endif + + for (i = 0; i < size; ++i, ++a) if (*a != 0) return 0; return 1; @@ -393,7 +451,7 @@ int git_oid_shorten_add(git_oid_shorten *os, const char *text_oid) idx = 0; is_leaf = false; - for (i = 0; i < GIT_OID_HEXSZ; ++i) { + for (i = 0; i < GIT_OID_SHA1_HEXSIZE; ++i) { int c = git__fromhex(text_oid[i]); trie_node *node; diff --git a/src/libgit2/oid.h b/src/libgit2/oid.h index abae9a4b2..7b6b09d8b 100644 --- a/src/libgit2/oid.h +++ b/src/libgit2/oid.h @@ -9,11 +9,120 @@ #include "common.h" +#include "git2/experimental.h" #include "git2/oid.h" +#include "hash.h" + +#ifdef GIT_EXPERIMENTAL_SHA256 +# define GIT_OID_NONE { 0, { 0 } } +# define GIT_OID_INIT(type, ...) { type, __VA_ARGS__ } +#else +# define GIT_OID_NONE { { 0 } } +# define GIT_OID_INIT(type, ...) { __VA_ARGS__ } +#endif extern const git_oid git_oid__empty_blob_sha1; extern const git_oid git_oid__empty_tree_sha1; +GIT_INLINE(git_oid_t) git_oid_type(const git_oid *oid) +{ +#ifdef GIT_EXPERIMENTAL_SHA256 + return oid->type; +#else + GIT_UNUSED(oid); + return GIT_OID_SHA1; +#endif +} + +GIT_INLINE(size_t) git_oid_size(git_oid_t type) +{ + switch (type) { + case GIT_OID_SHA1: + return GIT_OID_SHA1_SIZE; + +#ifdef GIT_EXPERIMENTAL_SHA256 + case GIT_OID_SHA256: + return GIT_OID_SHA256_SIZE; +#endif + + } + + return 0; +} + +GIT_INLINE(size_t) git_oid_hexsize(git_oid_t type) +{ + switch (type) { + case GIT_OID_SHA1: + return GIT_OID_SHA1_HEXSIZE; + +#ifdef GIT_EXPERIMENTAL_SHA256 + case GIT_OID_SHA256: + return GIT_OID_SHA256_HEXSIZE; +#endif + + } + + return 0; +} + +GIT_INLINE(const char *) git_oid_type_name(git_oid_t type) +{ + switch (type) { + case GIT_OID_SHA1: + return "sha1"; + +#ifdef GIT_EXPERIMENTAL_SHA256 + case GIT_OID_SHA256: + return "sha256"; +#endif + } + + return "unknown"; +} + +GIT_INLINE(git_oid_t) git_oid_type_fromstr(const char *name) +{ + if (strcmp(name, "sha1") == 0) + return GIT_OID_SHA1; + +#ifdef GIT_EXPERIMENTAL_SHA256 + if (strcmp(name, "sha256") == 0) + return GIT_OID_SHA256; +#endif + + return 0; +} + +GIT_INLINE(git_oid_t) git_oid_type_fromstrn(const char *name, size_t len) +{ + if (len == CONST_STRLEN("sha1") && strncmp(name, "sha1", len) == 0) + return GIT_OID_SHA1; + +#ifdef GIT_EXPERIMENTAL_SHA256 + if (len == CONST_STRLEN("sha256") && strncmp(name, "sha256", len) == 0) + return GIT_OID_SHA256; +#endif + + return 0; +} + +GIT_INLINE(git_hash_algorithm_t) git_oid_algorithm(git_oid_t type) +{ + switch (type) { + case GIT_OID_SHA1: + return GIT_HASH_ALGORITHM_SHA1; + +#ifdef GIT_EXPERIMENTAL_SHA256 + case GIT_OID_SHA256: + return GIT_HASH_ALGORITHM_SHA256; +#endif + + } + + return 0; +} + /** * Format a git_oid into a newly allocated c-string. * @@ -25,13 +134,42 @@ extern const git_oid git_oid__empty_tree_sha1; */ char *git_oid_allocfmt(const git_oid *id); +/** + * Format the requested nibbles of an object id. + * + * @param str the string to write into + * @param oid the oid structure to format + * @param start the starting number of nibbles + * @param count the number of nibbles to format + */ +GIT_INLINE(void) git_oid_fmt_substr( + char *str, + const git_oid *oid, + size_t start, + size_t count) +{ + static char hex[] = "0123456789abcdef"; + size_t i, end = start + count, min = start / 2, max = end / 2; + + if (start & 1) + *str++ = hex[oid->id[min++] & 0x0f]; + + for (i = min; i < max; i++) { + *str++ = hex[oid->id[i] >> 4]; + *str++ = hex[oid->id[i] & 0x0f]; + } + + if (end & 1) + *str++ = hex[oid->id[i] >> 4]; +} + GIT_INLINE(int) git_oid_raw_ncmp( const unsigned char *sha1, const unsigned char *sha2, size_t len) { - if (len > GIT_OID_HEXSZ) - len = GIT_OID_HEXSZ; + if (len > GIT_OID_MAX_HEXSIZE) + len = GIT_OID_MAX_HEXSIZE; while (len > 1) { if (*sha1 != *sha2) @@ -50,16 +188,18 @@ GIT_INLINE(int) git_oid_raw_ncmp( GIT_INLINE(int) git_oid_raw_cmp( const unsigned char *sha1, - const unsigned char *sha2) + const unsigned char *sha2, + size_t size) { - return memcmp(sha1, sha2, GIT_OID_RAWSZ); + return memcmp(sha1, sha2, size); } GIT_INLINE(int) git_oid_raw_cpy( unsigned char *dst, - const unsigned char *src) + const unsigned char *src, + size_t size) { - memcpy(dst, src, GIT_OID_RAWSZ); + memcpy(dst, src, size); return 0; } @@ -72,19 +212,30 @@ GIT_INLINE(int) git_oid_raw_cpy( */ GIT_INLINE(int) git_oid__cmp(const git_oid *a, const git_oid *b) { - return git_oid_raw_cmp(a->id, b->id); +#ifdef GIT_EXPERIMENTAL_SHA256 + if (a->type != b->type) + return a->type - b->type; + + return git_oid_raw_cmp(a->id, b->id, git_oid_size(a->type)); +#else + return git_oid_raw_cmp(a->id, b->id, git_oid_size(GIT_OID_SHA1)); +#endif } GIT_INLINE(void) git_oid__cpy_prefix( git_oid *out, const git_oid *id, size_t len) { +#ifdef GIT_EXPERIMENTAL_SHA256 + out->type = id->type; +#endif + memcpy(&out->id, id->id, (len + 1) / 2); if (len & 1) out->id[len / 2] &= 0xF0; } -GIT_INLINE(bool) git_oid__is_hexstr(const char *str) +GIT_INLINE(bool) git_oid__is_hexstr(const char *str, git_oid_t type) { size_t i; @@ -93,7 +244,30 @@ GIT_INLINE(bool) git_oid__is_hexstr(const char *str) return false; } - return (i == GIT_OID_HEXSZ); + return (i == git_oid_hexsize(type)); } +GIT_INLINE(void) git_oid_clear(git_oid *out, git_oid_t type) +{ + memset(out->id, 0, git_oid_size(type)); + +#ifdef GIT_EXPERIMENTAL_SHA256 + out->type = type; +#endif +} + +/* SHA256 support */ + +int git_oid__fromstr(git_oid *out, const char *str, git_oid_t type); + +int git_oid__fromstrp(git_oid *out, const char *str, git_oid_t type); + +int git_oid__fromstrn( + git_oid *out, + const char *str, + size_t length, + git_oid_t type); + +int git_oid__fromraw(git_oid *out, const unsigned char *raw, git_oid_t type); + #endif diff --git a/src/libgit2/pack-objects.c b/src/libgit2/pack-objects.c index 1aa6731b3..20a5dfcbd 100644 --- a/src/libgit2/pack-objects.c +++ b/src/libgit2/pack-objects.c @@ -347,8 +347,8 @@ static int write_object( goto done; if (type == GIT_OBJECT_REF_DELTA) { - if ((error = write_cb(po->delta->id.id, GIT_OID_RAWSZ, cb_data)) < 0 || - (error = git_hash_update(&pb->ctx, po->delta->id.id, GIT_OID_RAWSZ)) < 0) + if ((error = write_cb(po->delta->id.id, GIT_OID_SHA1_SIZE, cb_data)) < 0 || + (error = git_hash_update(&pb->ctx, po->delta->id.id, GIT_OID_SHA1_SIZE)) < 0) goto done; } @@ -668,7 +668,7 @@ static int write_pack(git_packbuilder *pb, if ((error = git_hash_final(entry_oid.id, &pb->ctx)) < 0) goto done; - error = write_cb(entry_oid.id, GIT_OID_RAWSZ, cb_data); + error = write_cb(entry_oid.id, GIT_OID_SHA1_SIZE, cb_data); done: /* if callback cancelled writing, we must still free delta_data */ @@ -1407,7 +1407,18 @@ int git_packbuilder_write( opts.progress_cb = progress_cb; opts.progress_cb_payload = progress_cb_payload; - if ((error = git_indexer_new(&indexer, path, mode, pb->odb, &opts)) < 0) + /* TODO: SHA256 */ + +#ifdef GIT_EXPERIMENTAL_SHA256 + opts.mode = mode; + opts.odb = pb->odb; + + error = git_indexer_new(&indexer, path, GIT_OID_SHA1, &opts); +#else + error = git_indexer_new(&indexer, path, mode, pb->odb, &opts); +#endif + + if (error < 0) goto cleanup; if (!git_repository__configmap_lookup(&t, pb->repo, GIT_CONFIGMAP_FSYNCOBJECTFILES) && t) diff --git a/src/libgit2/pack.c b/src/libgit2/pack.c index 16fe378bd..d59973aa9 100644 --- a/src/libgit2/pack.c +++ b/src/libgit2/pack.c @@ -32,7 +32,7 @@ static int packfile_unpack_compressed( * Throws GIT_EAMBIGUOUSOIDPREFIX if short oid * is ambiguous within the pack. * This method assumes that len is between - * GIT_OID_MINPREFIXLEN and GIT_OID_HEXSZ. + * GIT_OID_MINPREFIXLEN and the oid type's hexsize. */ static int pack_entry_find_offset( off64_t *offset_out, @@ -186,9 +186,9 @@ static int cache_add( static void pack_index_free(struct git_pack_file *p) { - if (p->oids) { - git__free(p->oids); - p->oids = NULL; + if (p->ids) { + git__free(p->ids); + p->ids = NULL; } if (p->index_map.data) { git_futils_mmap_free(&p->index_map); @@ -200,11 +200,12 @@ static void pack_index_free(struct git_pack_file *p) static int pack_index_check_locked(const char *path, struct git_pack_file *p) { struct git_pack_idx_header *hdr; - uint32_t version, nr, i, *index; + uint32_t version, nr = 0, i, *index; void *idx_map; size_t idx_size; struct stat st; int error; + /* TODO: properly open the file without access time using O_NOATIME */ git_file fd = git_futils_open_ro(path); if (fd < 0) @@ -218,8 +219,7 @@ static int pack_index_check_locked(const char *path, struct git_pack_file *p) if (!S_ISREG(st.st_mode) || !git__is_sizet(st.st_size) || - (idx_size = (size_t)st.st_size) < 4 * 256 + 20 + 20) - { + (idx_size = (size_t)st.st_size) < (size_t)((4 * 256) + (p->oid_size * 2))) { p_close(fd); git_error_set(GIT_ERROR_ODB, "invalid pack index '%s'", path); return -1; @@ -242,10 +242,10 @@ static int pack_index_check_locked(const char *path, struct git_pack_file *p) return packfile_error("unsupported index version"); } - } else + } else { version = 1; + } - nr = 0; index = idx_map; if (version > 1) @@ -264,11 +264,11 @@ static int pack_index_check_locked(const char *path, struct git_pack_file *p) /* * Total size: * - 256 index entries 4 bytes each - * - 24-byte entries * nr (20-byte sha1 + 4-byte offset) - * - 20-byte SHA1 of the packfile - * - 20-byte SHA1 file checksum + * - 24/36-byte entries * nr (20/32 byte SHA + 4-byte offset) + * - 20/32-byte SHA of the packfile + * - 20/32-byte SHA file checksum */ - if (idx_size != 4*256 + nr * 24 + 20 + 20) { + if (idx_size != (4 * 256 + ((uint64_t) nr * (p->oid_size + 4)) + (p->oid_size * 2))) { git_futils_mmap_free(&p->index_map); return packfile_error("index is corrupted"); } @@ -277,17 +277,17 @@ static int pack_index_check_locked(const char *path, struct git_pack_file *p) * Minimum size: * - 8 bytes of header * - 256 index entries 4 bytes each - * - 20-byte sha1 entry * nr + * - 20/32-byte SHA entry * nr * - 4-byte crc entry * nr * - 4-byte offset entry * nr - * - 20-byte SHA1 of the packfile - * - 20-byte SHA1 file checksum + * - 20/32-byte SHA of the packfile + * - 20/32-byte SHA file checksum * And after the 4-byte offset table might be a * variable sized table containing 8-byte entries * for offsets larger than 2^31. */ - unsigned long min_size = 8 + 4*256 + nr*(20 + 4 + 4) + 20 + 20; - unsigned long max_size = min_size; + uint64_t min_size = 8 + (4 * 256) + ((uint64_t)nr * (p->oid_size + 4 + 4)) + (p->oid_size * 2); + uint64_t max_size = min_size; if (nr) max_size += (nr - 1)*8; @@ -365,12 +365,12 @@ static unsigned char *pack_window_open( * Don't allow a negative offset, as that means we've wrapped * around. */ - if (offset > (p->mwf.size - 20)) + if (offset > (p->mwf.size - p->oid_size)) goto cleanup; if (offset < 0) goto cleanup; - pack_data = git_mwindow_open(&p->mwf, w_cursor, offset, 20, left); + pack_data = git_mwindow_open(&p->mwf, w_cursor, offset, p->oid_size, left); cleanup: git_mutex_unlock(&p->mwf.lock); @@ -473,13 +473,13 @@ int git_packfile_unpack_header( return error; } - /* pack_window_open() assures us we have [base, base + 20) available - * as a range that we can look at at. (Its actually the hash - * size that is assured.) With our object header encoding - * the maximum deflated object size is 2^137, which is just - * insane, so we know won't exceed what we have been given. + /* pack_window_open() assures us we have [base, base + oid_size) + * available as a range that we can look at at. (It's actually + * the hash size that is assured.) With our object header + * encoding the maximum deflated object size is 2^137, which is + * just insane, so we know won't exceed what we have been given. */ - base = git_mwindow_open(&p->mwf, w_curs, *curpos, 20, &left); + base = git_mwindow_open(&p->mwf, w_curs, *curpos, p->oid_size, &left); git_mutex_unlock(&p->lock); git_mutex_unlock(&p->mwf.lock); if (base == NULL) @@ -977,11 +977,12 @@ int get_delta_base( /* Assumption: the only reason this would fail is because the file is too small */ if (base_info == NULL) return GIT_EBUFS; - /* pack_window_open() assured us we have [base_info, base_info + 20) - * as a range that we can look at without walking off the - * end of the mapped window. Its actually the hash size - * that is assured. An OFS_DELTA longer than the hash size - * is stupid, as then a REF_DELTA would be smaller to store. + /* pack_window_open() assured us we have + * [base_info, base_info + oid_size) as a range that we can look + * at without walking off the end of the mapped window. Its + * actually the hash size that is assured. An OFS_DELTA longer + * than the hash size is stupid, as then a REF_DELTA would be + * smaller to store. */ if (type == GIT_OBJECT_OFS_DELTA) { unsigned used = 0; @@ -1002,7 +1003,7 @@ int get_delta_base( *curpos += used; } else if (type == GIT_OBJECT_REF_DELTA) { git_oid base_oid; - git_oid_fromraw(&base_oid, base_info); + git_oid__fromraw(&base_oid, base_info, p->oid_type); /* If we have the cooperative cache, search in it first */ if (p->has_cache) { @@ -1012,7 +1013,7 @@ int get_delta_base( if (entry->offset == 0) return packfile_error("delta offset is zero"); - *curpos += 20; + *curpos += p->oid_size; *delta_base_out = entry->offset; return 0; } else { @@ -1025,9 +1026,9 @@ int get_delta_base( } /* The base entry _must_ be in the same pack */ - if (pack_entry_find_offset(&base_offset, &unused, p, &base_oid, GIT_OID_HEXSZ) < 0) + if (pack_entry_find_offset(&base_offset, &unused, p, &base_oid, p->oid_hexsize) < 0) return packfile_error("base entry delta is not in the same pack"); - *curpos += 20; + *curpos += p->oid_size; } else return packfile_error("unknown object type"); @@ -1070,7 +1071,7 @@ void git_packfile_free(struct git_pack_file *p, bool unlink_packfile) pack_index_free(p); - git__free(p->bad_object_sha1); + git__free(p->bad_object_ids); git_mutex_free(&p->bases.lock); git_mutex_free(&p->mwf.lock); @@ -1083,8 +1084,8 @@ static int packfile_open_locked(struct git_pack_file *p) { struct stat st; struct git_pack_header hdr; - unsigned char sha1[GIT_OID_RAWSZ]; - unsigned char *idx_sha1; + unsigned char checksum[GIT_OID_MAX_SIZE]; + unsigned char *idx_checksum; if (pack_index_open_locked(p) < 0) return git_odb__error_notfound("failed to open packfile", NULL, 0); @@ -1131,12 +1132,13 @@ static int packfile_open_locked(struct git_pack_file *p) /* Verify the pack matches its index. */ if (p->num_objects != ntohl(hdr.hdr_entries) || - p_pread(p->mwf.fd, sha1, GIT_OID_RAWSZ, p->mwf.size - GIT_OID_RAWSZ) < 0) + p_pread(p->mwf.fd, checksum, p->oid_size, p->mwf.size - p->oid_size) < 0) goto cleanup; - idx_sha1 = ((unsigned char *)p->index_map.data) + p->index_map.len - 40; + idx_checksum = ((unsigned char *)p->index_map.data) + + p->index_map.len - (p->oid_size * 2); - if (git_oid_raw_cmp(sha1, idx_sha1) != 0) + if (git_oid_raw_cmp(checksum, idx_checksum, p->oid_size) != 0) goto cleanup; if (git_mwindow_file_register(&p->mwf) < 0) @@ -1171,7 +1173,10 @@ int git_packfile__name(char **out, const char *path) return 0; } -int git_packfile_alloc(struct git_pack_file **pack_out, const char *path) +int git_packfile_alloc( + struct git_pack_file **pack_out, + const char *path, + git_oid_t oid_type) { struct stat st; struct git_pack_file *p; @@ -1219,6 +1224,9 @@ int git_packfile_alloc(struct git_pack_file **pack_out, const char *path) p->pack_local = 1; p->mtime = (git_time_t)st.st_mtime; p->index_version = -1; + p->oid_type = oid_type ? oid_type : GIT_OID_DEFAULT; + p->oid_size = (unsigned int)git_oid_size(p->oid_type); + p->oid_hexsize = (unsigned int)git_oid_hexsize(p->oid_type); if (git_mutex_init(&p->lock) < 0) { git_error_set(GIT_ERROR_OS, "failed to initialize packfile mutex"); @@ -1260,9 +1268,9 @@ static off64_t nth_packed_object_offset_locked(struct git_pack_file *p, uint32_t end = index + p->index_map.len; index += 4 * 256; if (p->index_version == 1) - return ntohl(*((uint32_t *)(index + 24 * n))); + return ntohl(*((uint32_t *)(index + (p->oid_size + 4) * n))); - index += 8 + p->num_objects * (20 + 4); + index += 8 + p->num_objects * (p->oid_size + 4); off32 = ntohl(*((uint32_t *)(index + 4 * n))); if (!(off32 & 0x80000000)) return off32; @@ -1273,7 +1281,7 @@ static off64_t nth_packed_object_offset_locked(struct git_pack_file *p, uint32_t return -1; return (((uint64_t)ntohl(*((uint32_t *)(index + 0)))) << 32) | - ntohl(*((uint32_t *)(index + 4))); + ntohl(*((uint32_t *)(index + 4))); } static int git__memcmp4(const void *a, const void *b) { @@ -1312,7 +1320,7 @@ int git_pack_foreach_entry( index += 4 * 256; - if (p->oids == NULL) { + if (p->ids == NULL) { git_vector offsets, oids; if ((error = git_vector_init(&oids, p->num_objects, NULL))) { @@ -1326,22 +1334,25 @@ int git_pack_foreach_entry( } if (p->index_version > 1) { - const unsigned char *off = index + 24 * p->num_objects; + const unsigned char *off = index + + (p->oid_size + 4) * p->num_objects; + for (i = 0; i < p->num_objects; i++) git_vector_insert(&offsets, (void*)&off[4 * i]); + git_vector_sort(&offsets); git_vector_foreach(&offsets, i, current) git_vector_insert(&oids, (void*)&index[5 * (current - off)]); } else { for (i = 0; i < p->num_objects; i++) - git_vector_insert(&offsets, (void*)&index[24 * i]); + git_vector_insert(&offsets, (void*)&index[(p->oid_size + 4) * i]); git_vector_sort(&offsets); git_vector_foreach(&offsets, i, current) git_vector_insert(&oids, (void*)¤t[4]); } git_vector_free(&offsets); - p->oids = (unsigned char **)git_vector_detach(NULL, NULL, &oids); + p->ids = (unsigned char **)git_vector_detach(NULL, NULL, &oids); } /* @@ -1362,7 +1373,7 @@ int git_pack_foreach_entry( git_array_clear(oids); GIT_ERROR_CHECK_ALLOC(oid); } - git_oid_fromraw(oid, p->oids[i]); + git_oid__fromraw(oid, p->ids[i], p->oid_type); } git_mutex_unlock(&p->lock); @@ -1412,10 +1423,13 @@ int git_pack_foreach_entry_offset( /* all offsets should have been validated by pack_index_check_locked */ if (p->index_version > 1) { - const unsigned char *offsets = index + 24 * p->num_objects; + const unsigned char *offsets = index + + (p->oid_size + 4) * p->num_objects; const unsigned char *large_offset_ptr; - const unsigned char *large_offsets = index + 28 * p->num_objects; - const unsigned char *large_offsets_end = ((const unsigned char *)p->index_map.data) + p->index_map.len - 20; + const unsigned char *large_offsets = index + + (p->oid_size + 8) * p->num_objects; + const unsigned char *large_offsets_end = ((const unsigned char *)p->index_map.data) + p->index_map.len - p->oid_size; + for (i = 0; i < p->num_objects; i++) { current_offset = ntohl(*(const uint32_t *)(offsets + 4 * i)); if (current_offset & 0x80000000) { @@ -1428,7 +1442,7 @@ int git_pack_foreach_entry_offset( ntohl(*((uint32_t *)(large_offset_ptr + 4))); } - git_oid_fromraw(¤t_oid, (index + 20 * i)); + git_oid__fromraw(¤t_oid, (index + p->oid_size * i), p->oid_type); if ((error = cb(¤t_oid, current_offset, data)) != 0) { error = git_error_set_after_callback(error); goto cleanup; @@ -1436,8 +1450,8 @@ int git_pack_foreach_entry_offset( } } else { for (i = 0; i < p->num_objects; i++) { - current_offset = ntohl(*(const uint32_t *)(index + 24 * i)); - git_oid_fromraw(¤t_oid, (index + 24 * i + 4)); + current_offset = ntohl(*(const uint32_t *)(index + (p->oid_size + 4) * i)); + git_oid__fromraw(¤t_oid, (index + (p->oid_size + 4) * i + 4), p->oid_type); if ((error = cb(¤t_oid, current_offset, data)) != 0) { error = git_error_set_after_callback(error); goto cleanup; @@ -1450,14 +1464,20 @@ cleanup: return error; } -int git_pack__lookup_sha1(const void *oid_lookup_table, size_t stride, unsigned lo, - unsigned hi, const unsigned char *oid_prefix) +int git_pack__lookup_id( + const void *oid_lookup_table, + size_t stride, + unsigned lo, + unsigned hi, + const unsigned char *oid_prefix, + const git_oid_t oid_type) { const unsigned char *base = oid_lookup_table; + size_t oid_size = git_oid_size(oid_type); while (lo < hi) { unsigned mi = (lo + hi) / 2; - int cmp = git_oid_raw_cmp(base + mi * stride, oid_prefix); + int cmp = git_oid_raw_cmp(base + mi * stride, oid_prefix, oid_size); if (!cmp) return mi; @@ -1512,9 +1532,9 @@ static int pack_entry_find_offset( lo = ((short_oid->id[0] == 0x0) ? 0 : ntohl(level1_ofs[(int)short_oid->id[0] - 1])); if (p->index_version > 1) { - stride = 20; + stride = p->oid_size; } else { - stride = 24; + stride = p->oid_size + 4; index += 4; } @@ -1523,7 +1543,8 @@ static int pack_entry_find_offset( short_oid->id[0], short_oid->id[1], short_oid->id[2], lo, hi, p->num_objects); #endif - pos = git_pack__lookup_sha1(index, stride, lo, hi, short_oid->id); + pos = git_pack__lookup_id(index, stride, lo, hi, + short_oid->id, p->oid_type); if (pos >= 0) { /* An object matching exactly the oid was found */ @@ -1541,7 +1562,9 @@ static int pack_entry_find_offset( } } - if (found && len != GIT_OID_HEXSZ && pos + 1 < (int)p->num_objects) { + if (found && + len != p->oid_hexsize && + pos + 1 < (int)p->num_objects) { /* Check for ambiguousity */ const unsigned char *next = current + stride; @@ -1566,13 +1589,13 @@ static int pack_entry_find_offset( } *offset_out = offset; - git_oid_fromraw(found_oid, current); + git_oid__fromraw(found_oid, current, p->oid_type); #ifdef INDEX_DEBUG_LOOKUP { - unsigned char hex_sha1[GIT_OID_HEXSZ + 1]; + char hex_sha1[p->oid_hexsize + 1]; git_oid_fmt(hex_sha1, found_oid); - hex_sha1[GIT_OID_HEXSZ] = '\0'; + hex_sha1[p->oid_hexsize] = '\0'; printf("found lo=%d %s\n", lo, hex_sha1); } #endif @@ -1594,10 +1617,10 @@ int git_pack_entry_find( GIT_ASSERT_ARG(p); - if (len == GIT_OID_HEXSZ && p->num_bad_objects) { + if (len == p->oid_hexsize && p->num_bad_objects) { unsigned i; for (i = 0; i < p->num_bad_objects; i++) - if (git_oid__cmp(short_oid, &p->bad_object_sha1[i]) == 0) + if (git_oid__cmp(short_oid, &p->bad_object_ids[i]) == 0) return packfile_error("bad object found in packfile"); } @@ -1630,6 +1653,6 @@ int git_pack_entry_find( e->offset = offset; e->p = p; - git_oid_cpy(&e->sha1, &found_oid); + git_oid_cpy(&e->id, &found_oid); return 0; } diff --git a/src/libgit2/pack.h b/src/libgit2/pack.h index d90588f79..1a9eb14b2 100644 --- a/src/libgit2/pack.h +++ b/src/libgit2/pack.h @@ -99,13 +99,19 @@ struct git_pack_file { uint32_t num_objects; uint32_t num_bad_objects; - git_oid *bad_object_sha1; /* array of git_oid */ + git_oid *bad_object_ids; /* array of git_oid */ + + git_oid_t oid_type; + unsigned oid_hexsize:7, + oid_size:6, + pack_local:1, + pack_keep:1, + has_cache:1; int index_version; git_time_t mtime; - unsigned pack_local:1, pack_keep:1, has_cache:1; git_oidmap *idx_cache; - unsigned char **oids; + unsigned char **ids; git_pack_cache bases; /* delta base cache */ @@ -116,21 +122,26 @@ struct git_pack_file { }; /** - * Return the position where an OID (or a prefix) would be inserted within the - * OID Lookup Table of an .idx file. This performs binary search between the lo - * and hi indices. + * Return the position where an OID (or a prefix) would be inserted within + * the OID Lookup Table of an .idx file. This performs binary search + * between the lo and hi indices. * - * The stride parameter is provided because .idx files version 1 store the OIDs - * interleaved with the 4-byte file offsets of the objects within the .pack - * file (stride = 24), whereas files with version 2 store them in a contiguous - * flat array (stride = 20). + * The stride parameter is provided because .idx files version 1 store the + * OIDs interleaved with the 4-byte file offsets of the objects within the + * .pack file (stride = oid_size + 4), whereas files with version 2 store + * them in a contiguous flat array (stride = oid_size). */ -int git_pack__lookup_sha1(const void *oid_lookup_table, size_t stride, unsigned lo, - unsigned hi, const unsigned char *oid_prefix); +int git_pack__lookup_id( + const void *id_lookup_table, + size_t stride, + unsigned lo, + unsigned hi, + const unsigned char *id_prefix, + const git_oid_t oid_type); struct git_pack_entry { off64_t offset; - git_oid sha1; + git_oid id; struct git_pack_file *p; }; @@ -174,12 +185,15 @@ int get_delta_base( off64_t delta_obj_offset); void git_packfile_free(struct git_pack_file *p, bool unlink_packfile); -int git_packfile_alloc(struct git_pack_file **pack_out, const char *path); +int git_packfile_alloc( + struct git_pack_file **pack_out, + const char *path, + git_oid_t oid_type); int git_pack_entry_find( struct git_pack_entry *e, struct git_pack_file *p, - const git_oid *short_oid, + const git_oid *short_id, size_t len); int git_pack_foreach_entry( struct git_pack_file *p, diff --git a/src/libgit2/parse.c b/src/libgit2/parse.c index 0a10758bf..55d3cb10e 100644 --- a/src/libgit2/parse.c +++ b/src/libgit2/parse.c @@ -5,6 +5,7 @@ * a Linking Exception. For full terms see the included COPYING file. */ #include "parse.h" +#include "oid.h" int git_parse_ctx_init(git_parse_ctx *ctx, const char *content, size_t content_len) { @@ -103,11 +104,11 @@ int git_parse_advance_digit(int64_t *out, git_parse_ctx *ctx, int base) int git_parse_advance_oid(git_oid *out, git_parse_ctx *ctx) { - if (ctx->line_len < GIT_OID_HEXSZ) + if (ctx->line_len < GIT_OID_SHA1_HEXSIZE) return -1; - if ((git_oid_fromstrn(out, ctx->line, GIT_OID_HEXSZ)) < 0) + if ((git_oid__fromstrn(out, ctx->line, GIT_OID_SHA1_HEXSIZE, GIT_OID_SHA1)) < 0) return -1; - git_parse_advance_chars(ctx, GIT_OID_HEXSZ); + git_parse_advance_chars(ctx, GIT_OID_SHA1_HEXSIZE); return 0; } diff --git a/src/libgit2/patch_parse.c b/src/libgit2/patch_parse.c index 78cd96252..ffdb99231 100644 --- a/src/libgit2/patch_parse.c +++ b/src/libgit2/patch_parse.c @@ -168,13 +168,13 @@ static int parse_header_oid( { size_t len; - for (len = 0; len < ctx->parse_ctx.line_len && len < GIT_OID_HEXSZ; len++) { + for (len = 0; len < ctx->parse_ctx.line_len && len < GIT_OID_SHA1_HEXSIZE; len++) { if (!git__isxdigit(ctx->parse_ctx.line[len])) break; } - if (len < GIT_OID_MINPREFIXLEN || len > GIT_OID_HEXSZ || - git_oid_fromstrn(oid, ctx->parse_ctx.line, len) < 0) + if (len < GIT_OID_MINPREFIXLEN || len > GIT_OID_SHA1_HEXSIZE || + git_oid__fromstrn(oid, ctx->parse_ctx.line, len, GIT_OID_SHA1) < 0) return git_parse_err("invalid hex formatted object id at line %"PRIuZ, ctx->parse_ctx.line_num); @@ -1065,12 +1065,12 @@ static int check_patch(git_patch_parsed *patch) return git_parse_err("patch with no hunks"); if (delta->status == GIT_DELTA_ADDED) { - memset(&delta->old_file.id, 0x0, sizeof(git_oid)); + git_oid_clear(&delta->old_file.id, GIT_OID_SHA1); delta->old_file.id_abbrev = 0; } if (delta->status == GIT_DELTA_DELETED) { - memset(&delta->new_file.id, 0x0, sizeof(git_oid)); + git_oid_clear(&delta->new_file.id, GIT_OID_SHA1); delta->new_file.id_abbrev = 0; } diff --git a/src/libgit2/push.c b/src/libgit2/push.c index da8aebadd..e25681870 100644 --- a/src/libgit2/push.c +++ b/src/libgit2/push.c @@ -118,6 +118,9 @@ static int parse_refspec(git_push *push, push_spec **spec, const char *str) s = git__calloc(1, sizeof(*s)); GIT_ERROR_CHECK_ALLOC(s); + git_oid_clear(&s->loid, GIT_OID_SHA1); + git_oid_clear(&s->roid, GIT_OID_SHA1); + if (git_refspec__parse(&s->refspec, str, false) < 0) { git_error_set(GIT_ERROR_INVALID, "invalid refspec %s", str); goto on_error; @@ -382,11 +385,18 @@ static int calculate_work(git_push *push) git_vector_foreach(&push->specs, i, spec) { if (spec->refspec.src && spec->refspec.src[0]!= '\0') { /* This is a create or update. Local ref must exist. */ - if (git_reference_name_to_id( - &spec->loid, push->repo, spec->refspec.src) < 0) { - git_error_set(GIT_ERROR_REFERENCE, "no such reference '%s'", spec->refspec.src); + + git_object *obj; + int error = git_revparse_single(&obj, push->repo, spec->refspec.src); + + if (error < 0) { + git_object_free(obj); + git_error_set(GIT_ERROR_REFERENCE, "src refspec %s does not match any", spec->refspec.src); return -1; } + + git_oid_cpy(&spec->loid, git_object_id(obj)); + git_object_free(obj); } /* Remote ref may or may not (e.g. during create) already exist. */ diff --git a/src/libgit2/reader.c b/src/libgit2/reader.c index ba9775240..be29bb41c 100644 --- a/src/libgit2/reader.c +++ b/src/libgit2/reader.c @@ -125,7 +125,7 @@ static int workdir_reader_read( goto done; if (out_id || reader->index) { - if ((error = git_odb_hash(&id, out->ptr, out->size, GIT_OBJECT_BLOB)) < 0) + if ((error = git_odb__hash(&id, out->ptr, out->size, GIT_OBJECT_BLOB, GIT_OID_SHA1)) < 0) goto done; } diff --git a/src/libgit2/rebase.c b/src/libgit2/rebase.c index 5e48f0dfb..1970d5ddc 100644 --- a/src/libgit2/rebase.c +++ b/src/libgit2/rebase.c @@ -181,7 +181,8 @@ GIT_INLINE(int) rebase_readoid( if ((error = rebase_readfile(str_out, state_path, filename)) < 0) return error; - if (str_out->size != GIT_OID_HEXSZ || git_oid_fromstr(out, str_out->ptr) < 0) { + if (str_out->size != GIT_OID_SHA1_HEXSIZE || + git_oid__fromstr(out, str_out->ptr, GIT_OID_SHA1) < 0) { git_error_set(GIT_ERROR_REBASE, "the file '%s' contains an invalid object ID", filename); return -1; } @@ -363,7 +364,7 @@ int git_rebase_open( git_str_rtrim(&orig_head_id); - if ((error = git_oid_fromstr(&rebase->orig_head_id, orig_head_id.ptr)) < 0) + if ((error = git_oid__fromstr(&rebase->orig_head_id, orig_head_id.ptr, GIT_OID_SHA1)) < 0) goto done; git_str_truncate(&path, state_path_len); @@ -374,7 +375,7 @@ int git_rebase_open( git_str_rtrim(&onto_id); - if ((error = git_oid_fromstr(&rebase->onto_id, onto_id.ptr)) < 0) + if ((error = git_oid__fromstr(&rebase->onto_id, onto_id.ptr, GIT_OID_SHA1)) < 0) goto done; if (!rebase->head_detached) @@ -452,7 +453,7 @@ static const char *rebase_onto_name(const git_annotated_commit *onto) static int rebase_setupfiles_merge(git_rebase *rebase) { git_str commit_filename = GIT_STR_INIT; - char id_str[GIT_OID_HEXSZ]; + char id_str[GIT_OID_SHA1_HEXSIZE]; git_rebase_operation *operation; size_t i; int error = 0; @@ -470,7 +471,7 @@ static int rebase_setupfiles_merge(git_rebase *rebase) git_oid_fmt(id_str, &operation->id); if ((error = rebase_setupfile(rebase, commit_filename.ptr, 0, - "%.*s\n", GIT_OID_HEXSZ, id_str)) < 0) + "%.*s\n", GIT_OID_SHA1_HEXSIZE, id_str)) < 0) goto done; } @@ -481,7 +482,7 @@ done: static int rebase_setupfiles(git_rebase *rebase) { - char onto[GIT_OID_HEXSZ], orig_head[GIT_OID_HEXSZ]; + char onto[GIT_OID_SHA1_HEXSIZE], orig_head[GIT_OID_SHA1_HEXSIZE]; const char *orig_head_name; git_oid_fmt(onto, &rebase->onto_id); @@ -497,8 +498,8 @@ static int rebase_setupfiles(git_rebase *rebase) if (git_repository__set_orig_head(rebase->repo, &rebase->orig_head_id) < 0 || rebase_setupfile(rebase, HEAD_NAME_FILE, 0, "%s\n", orig_head_name) < 0 || - rebase_setupfile(rebase, ONTO_FILE, 0, "%.*s\n", GIT_OID_HEXSZ, onto) < 0 || - rebase_setupfile(rebase, ORIG_HEAD_FILE, 0, "%.*s\n", GIT_OID_HEXSZ, orig_head) < 0 || + rebase_setupfile(rebase, ONTO_FILE, 0, "%.*s\n", GIT_OID_SHA1_HEXSIZE, onto) < 0 || + rebase_setupfile(rebase, ORIG_HEAD_FILE, 0, "%.*s\n", GIT_OID_SHA1_HEXSIZE, orig_head) < 0 || rebase_setupfile(rebase, QUIET_FILE, 0, rebase->quiet ? "t\n" : "\n") < 0) return -1; @@ -813,7 +814,7 @@ static int rebase_next_merge( git_indexwriter indexwriter = GIT_INDEXWRITER_INIT; git_rebase_operation *operation; git_checkout_options checkout_opts; - char current_idstr[GIT_OID_HEXSZ]; + char current_idstr[GIT_OID_SHA1_HEXSIZE]; unsigned int parent_count; int error; @@ -842,7 +843,7 @@ static int rebase_next_merge( if ((error = git_indexwriter_init_for_operation(&indexwriter, rebase->repo, &checkout_opts.checkout_strategy)) < 0 || (error = rebase_setupfile(rebase, MSGNUM_FILE, 0, "%" PRIuZ "\n", rebase->current+1)) < 0 || - (error = rebase_setupfile(rebase, CURRENT_FILE, 0, "%.*s\n", GIT_OID_HEXSZ, current_idstr)) < 0 || + (error = rebase_setupfile(rebase, CURRENT_FILE, 0, "%.*s\n", GIT_OID_SHA1_HEXSIZE, current_idstr)) < 0 || (error = git_merge_trees(&index, rebase->repo, parent_tree, head_tree, current_tree, &rebase->options.merge_options)) < 0 || (error = git_merge__check_result(rebase->repo, index)) < 0 || (error = git_checkout_index(rebase->repo, index, &checkout_opts)) < 0 || @@ -1102,7 +1103,7 @@ static int rebase_commit_merge( git_reference *head = NULL; git_commit *head_commit = NULL, *commit = NULL; git_index *index = NULL; - char old_idstr[GIT_OID_HEXSZ], new_idstr[GIT_OID_HEXSZ]; + char old_idstr[GIT_OID_SHA1_HEXSIZE], new_idstr[GIT_OID_SHA1_HEXSIZE]; int error; operation = git_array_get(rebase->operations, rebase->current); @@ -1122,7 +1123,7 @@ static int rebase_commit_merge( git_oid_fmt(new_idstr, git_commit_id(commit)); if ((error = rebase_setupfile(rebase, REWRITTEN_FILE, O_CREAT|O_WRONLY|O_APPEND, - "%.*s %.*s\n", GIT_OID_HEXSZ, old_idstr, GIT_OID_HEXSZ, new_idstr)) < 0) + "%.*s %.*s\n", GIT_OID_SHA1_HEXSIZE, old_idstr, GIT_OID_SHA1_HEXSIZE, new_idstr)) < 0) goto done; git_oid_cpy(commit_id, git_commit_id(commit)); @@ -1341,10 +1342,10 @@ static int rebase_copy_notes( tostr = end+1; *end = '\0'; - if (strlen(fromstr) != GIT_OID_HEXSZ || - strlen(tostr) != GIT_OID_HEXSZ || - git_oid_fromstr(&from, fromstr) < 0 || - git_oid_fromstr(&to, tostr) < 0) + if (strlen(fromstr) != GIT_OID_SHA1_HEXSIZE || + strlen(tostr) != GIT_OID_SHA1_HEXSIZE || + git_oid__fromstr(&from, fromstr, GIT_OID_SHA1) < 0 || + git_oid__fromstr(&to, tostr, GIT_OID_SHA1) < 0) goto on_error; if ((error = rebase_copy_note(rebase, notes_ref.ptr, &from, &to, committer)) < 0) @@ -1372,14 +1373,14 @@ static int return_to_orig_head(git_rebase *rebase) git_reference *terminal_ref = NULL, *branch_ref = NULL, *head_ref = NULL; git_commit *terminal_commit = NULL; git_str branch_msg = GIT_STR_INIT, head_msg = GIT_STR_INIT; - char onto[GIT_OID_HEXSZ]; + char onto[GIT_OID_SHA1_HEXSIZE]; int error = 0; git_oid_fmt(onto, &rebase->onto_id); if ((error = git_str_printf(&branch_msg, "rebase finished: %s onto %.*s", - rebase->orig_head_name, GIT_OID_HEXSZ, onto)) == 0 && + rebase->orig_head_name, GIT_OID_SHA1_HEXSIZE, onto)) == 0 && (error = git_str_printf(&head_msg, "rebase finished: returning to %s", rebase->orig_head_name)) == 0 && diff --git a/src/libgit2/refdb_fs.c b/src/libgit2/refdb_fs.c index 0f49b16bb..9ce1a9608 100644 --- a/src/libgit2/refdb_fs.c +++ b/src/libgit2/refdb_fs.c @@ -60,15 +60,17 @@ typedef struct refdb_fs_backend { /* path to common objects' directory */ char *commonpath; - git_sortedcache *refcache; + git_oid_t oid_type; + + int fsync : 1, + sorted : 1; int peeling_mode; git_iterator_flag_t iterator_flags; uint32_t direach_flags; - int fsync; + git_sortedcache *refcache; git_map packed_refs_map; git_mutex prlock; /* protect packed_refs_map */ git_futils_filestamp packed_refs_stamp; - bool sorted; } refdb_fs_backend; static int refdb_reflog_fs__delete(git_refdb_backend *_backend, const char *name); @@ -113,6 +115,7 @@ static int packed_reload(refdb_fs_backend *backend) { int error; git_str packedrefs = GIT_STR_INIT; + size_t oid_hexsize = git_oid_hexsize(backend->oid_type); char *scan, *eof, *eol; if (!backend->gitpath) @@ -158,9 +161,9 @@ static int packed_reload(refdb_fs_backend *backend) /* parse " \n" */ - if (git_oid_fromstr(&oid, scan) < 0) + if (git_oid__fromstr(&oid, scan, backend->oid_type) < 0) goto parse_failed; - scan += GIT_OID_HEXSZ; + scan += oid_hexsize; if (*scan++ != ' ') goto parse_failed; @@ -179,9 +182,9 @@ static int packed_reload(refdb_fs_backend *backend) /* look for optional "^\n" */ if (*scan == '^') { - if (git_oid_fromstr(&oid, scan + 1) < 0) + if (git_oid__fromstr(&oid, scan + 1, backend->oid_type) < 0) goto parse_failed; - scan += GIT_OID_HEXSZ + 1; + scan += oid_hexsize + 1; if (scan < eof) { if (!(eol = strchr(scan, '\n'))) @@ -214,19 +217,23 @@ parse_failed: } static int loose_parse_oid( - git_oid *oid, const char *filename, git_str *file_content) + git_oid *oid, + const char *filename, + git_str *file_content, + git_oid_t oid_type) { const char *str = git_str_cstr(file_content); + size_t oid_hexsize = git_oid_hexsize(oid_type); - if (git_str_len(file_content) < GIT_OID_HEXSZ) + if (git_str_len(file_content) < oid_hexsize) goto corrupted; /* we need to get 40 OID characters from the file */ - if (git_oid_fromstr(oid, str) < 0) + if (git_oid__fromstr(oid, str, oid_type) < 0) goto corrupted; /* If the file is longer than 40 chars, the 41st must be a space */ - str += GIT_OID_HEXSZ; + str += oid_hexsize; if (*str == '\0' || git__isspace(*str)) return 0; @@ -266,7 +273,7 @@ static int loose_lookup_to_packfile(refdb_fs_backend *backend, const char *name) goto done; /* parse OID from file */ - if ((error = loose_parse_oid(&oid, name, &ref_file)) < 0) + if ((error = loose_parse_oid(&oid, name, &ref_file, backend->oid_type)) < 0) goto done; if ((error = git_sortedcache_wlock(backend->refcache)) < 0) @@ -437,7 +444,7 @@ static int loose_lookup( } else { git_oid oid; - if (!(error = loose_parse_oid(&oid, ref_name, &ref_file)) && + if (!(error = loose_parse_oid(&oid, ref_name, &ref_file, backend->oid_type)) && out != NULL) *out = git_reference__alloc(ref_name, &oid, NULL); } @@ -615,19 +622,24 @@ static const char *end_of_record(const char *p, const char *end) return p; } -static int -cmp_record_to_refname(const char *rec, size_t data_end, const char *ref_name) +static int cmp_record_to_refname( + const char *rec, + size_t data_end, + const char *ref_name, + git_oid_t oid_type) { const size_t ref_len = strlen(ref_name); int cmp_val; const char *end; + size_t oid_hexsize = git_oid_hexsize(oid_type); - rec += GIT_OID_HEXSZ + 1; /* + space */ - if (data_end < GIT_OID_HEXSZ + 3) { - /* an incomplete (corrupt) record is treated as less than ref_name */ + rec += oid_hexsize + 1; /* + space */ + + /* an incomplete (corrupt) record is treated as less than ref_name */ + if (data_end < oid_hexsize + 3) return -1; - } - data_end -= GIT_OID_HEXSZ + 1; + + data_end -= oid_hexsize + 1; end = memchr(rec, '\n', data_end); if (end) @@ -675,6 +687,7 @@ static int packed_lookup( { int error = 0; const char *left, *right, *data_end; + size_t oid_hexsize = git_oid_hexsize(backend->oid_type); if ((error = packed_map_check(backend)) < 0) return error; @@ -698,7 +711,7 @@ static int packed_lookup( mid = left + (right - left) / 2; rec = start_of_record(left, mid); - compare = cmp_record_to_refname(rec, data_end - rec, ref_name); + compare = cmp_record_to_refname(rec, data_end - rec, ref_name, backend->oid_type); if (compare < 0) { left = end_of_record(mid, right); @@ -708,11 +721,11 @@ static int packed_lookup( const char *eol; git_oid oid, peel, *peel_ptr = NULL; - if (data_end - rec < GIT_OID_HEXSZ || - git_oid_fromstr(&oid, rec) < 0) { + if (data_end - rec < (long)oid_hexsize || + git_oid__fromstr(&oid, rec, backend->oid_type) < 0) { goto parse_failed; } - rec += GIT_OID_HEXSZ + 1; + rec += oid_hexsize + 1; if (!(eol = memchr(rec, '\n', data_end - rec))) { goto parse_failed; } @@ -724,8 +737,8 @@ static int packed_lookup( if (*rec == '^') { rec++; - if (data_end - rec < GIT_OID_HEXSZ || - git_oid_fromstr(&peel, rec) < 0) { + if (data_end - rec < (long)oid_hexsize || + git_oid__fromstr(&peel, rec, backend->oid_type) < 0) { goto parse_failed; } peel_ptr = &peel; @@ -1108,7 +1121,7 @@ static int loose_commit(git_filebuf *file, const git_reference *ref) GIT_ASSERT_ARG(ref); if (ref->type == GIT_REFERENCE_DIRECT) { - char oid[GIT_OID_HEXSZ + 1]; + char oid[GIT_OID_MAX_HEXSIZE + 1]; git_oid_nfmt(oid, sizeof(oid), &ref->target.oid); git_filebuf_printf(file, "%s\n", oid); @@ -1224,7 +1237,7 @@ static int packed_find_peel(refdb_fs_backend *backend, struct packref *ref) */ static int packed_write_ref(struct packref *ref, git_filebuf *file) { - char oid[GIT_OID_HEXSZ + 1]; + char oid[GIT_OID_MAX_HEXSIZE + 1]; git_oid_nfmt(oid, sizeof(oid), &ref->oid); /* @@ -1238,7 +1251,7 @@ static int packed_write_ref(struct packref *ref, git_filebuf *file) * The required peels have already been loaded into `ref->peel_target`. */ if (ref->flags & PACKREF_HAS_PEEL) { - char peel[GIT_OID_HEXSZ + 1]; + char peel[GIT_OID_MAX_HEXSIZE + 1]; git_oid_nfmt(peel, sizeof(peel), &ref->peel); if (git_filebuf_printf(file, "%s %s\n^%s\n", oid, ref->name, peel) < 0) @@ -1302,7 +1315,7 @@ static int packed_remove_loose(refdb_fs_backend *backend) continue; /* Figure out the current id; if we find a bad ref file, skip it so we can do the rest */ - if (loose_parse_oid(¤t_id, lock.path_original, &ref_content) < 0) + if (loose_parse_oid(¤t_id, lock.path_original, &ref_content, backend->oid_type) < 0) continue; /* If the ref moved since we packed it, we must not delete it */ @@ -1891,7 +1904,10 @@ done: return out; } -static int reflog_alloc(git_reflog **reflog, const char *name) +static int reflog_alloc( + git_reflog **reflog, + const char *name, + git_oid_t oid_type) { git_reflog *log; @@ -1903,6 +1919,8 @@ static int reflog_alloc(git_reflog **reflog, const char *name) log->ref_name = git__strdup(name); GIT_ERROR_CHECK_ALLOC(log->ref_name); + log->oid_type = oid_type; + if (git_vector_init(&log->entries, 0, NULL) < 0) { git__free(log->ref_name); git__free(log); @@ -2032,7 +2050,10 @@ static int refdb_reflog_fs__has_log(git_refdb_backend *_backend, const char *nam return has_reflog(backend->repo, name); } -static int refdb_reflog_fs__read(git_reflog **out, git_refdb_backend *_backend, const char *name) +static int refdb_reflog_fs__read( + git_reflog **out, + git_refdb_backend *_backend, + const char *name) { int error = -1; git_str log_path = GIT_STR_INIT; @@ -2048,7 +2069,7 @@ static int refdb_reflog_fs__read(git_reflog **out, git_refdb_backend *_backend, backend = GIT_CONTAINER_OF(_backend, refdb_fs_backend, parent); repo = backend->repo; - if (reflog_alloc(&log, name) < 0) + if (reflog_alloc(&log, name, backend->oid_type) < 0) return -1; if (reflog_path(&log_path, repo, name) < 0) @@ -2086,11 +2107,11 @@ static int serialize_reflog_entry( const git_signature *committer, const char *msg) { - char raw_old[GIT_OID_HEXSZ+1]; - char raw_new[GIT_OID_HEXSZ+1]; + char raw_old[GIT_OID_MAX_HEXSIZE + 1]; + char raw_new[GIT_OID_MAX_HEXSIZE + 1]; - git_oid_tostr(raw_old, GIT_OID_HEXSZ+1, oid_old); - git_oid_tostr(raw_new, GIT_OID_HEXSZ+1, oid_new); + git_oid_tostr(raw_old, GIT_OID_MAX_HEXSIZE + 1, oid_old); + git_oid_tostr(raw_new, GIT_OID_MAX_HEXSIZE + 1, oid_new); git_str_clear(buf); @@ -2189,10 +2210,16 @@ success: } /* Append to the reflog, must be called under reference lock */ -static int reflog_append(refdb_fs_backend *backend, const git_reference *ref, const git_oid *old, const git_oid *new, const git_signature *who, const char *message) +static int reflog_append( + refdb_fs_backend *backend, + const git_reference *ref, + const git_oid *old, + const git_oid *new, + const git_signature *who, + const char *message) { int error, is_symbolic, open_flags; - git_oid old_id = {{0}}, new_id = {{0}}; + git_oid old_id, new_id; git_str buf = GIT_STR_INIT, path = GIT_STR_INIT; git_repository *repo = backend->repo; @@ -2206,6 +2233,9 @@ static int reflog_append(refdb_fs_backend *backend, const git_reference *ref, co /* From here on is_symbolic also means that it's HEAD */ + git_oid_clear(&old_id, backend->oid_type); + git_oid_clear(&new_id, backend->oid_type); + if (old) { git_oid_cpy(&old_id, old); } else { @@ -2402,6 +2432,7 @@ int git_refdb_backend_fs( goto fail; backend->repo = repository; + backend->oid_type = repository->oid_type; if (repository->gitdir) { backend->gitpath = setup_namespace(repository, repository->gitdir); diff --git a/src/libgit2/reflog.c b/src/libgit2/reflog.c index 1e9c0d4f1..86d4355e3 100644 --- a/src/libgit2/reflog.c +++ b/src/libgit2/reflog.c @@ -71,7 +71,11 @@ int git_reflog_write(git_reflog *reflog) return db->backend->reflog_write(db->backend, reflog); } -int git_reflog_append(git_reflog *reflog, const git_oid *new_oid, const git_signature *committer, const char *msg) +int git_reflog_append( + git_reflog *reflog, + const git_oid *new_oid, + const git_signature *committer, + const char *msg) { const git_reflog_entry *previous; git_reflog_entry *entry; @@ -104,7 +108,7 @@ int git_reflog_append(git_reflog *reflog, const git_oid *new_oid, const git_sign previous = git_reflog_entry_byindex(reflog, 0); if (previous == NULL) - git_oid_fromstr(&entry->oid_old, GIT_OID_HEX_ZERO); + git_oid_clear(&entry->oid_old, reflog->oid_type); else git_oid_cpy(&entry->oid_old, &previous->oid_cur); @@ -219,9 +223,7 @@ int git_reflog_drop(git_reflog *reflog, size_t idx, int rewrite_previous_entry) /* If the oldest entry has just been removed... */ if (idx == entrycount - 1) { /* ...clear the oid_old member of the "new" oldest entry */ - if (git_oid_fromstr(&entry->oid_old, GIT_OID_HEX_ZERO) < 0) - return -1; - + git_oid_clear(&entry->oid_old, reflog->oid_type); return 0; } diff --git a/src/libgit2/reflog.h b/src/libgit2/reflog.h index 8c3895952..bc9878598 100644 --- a/src/libgit2/reflog.h +++ b/src/libgit2/reflog.h @@ -16,8 +16,6 @@ #define GIT_REFLOG_DIR_MODE 0777 #define GIT_REFLOG_FILE_MODE 0666 -#define GIT_REFLOG_SIZE_MIN (2*GIT_OID_HEXSZ+2+17) - struct git_reflog_entry { git_oid oid_old; git_oid oid_cur; @@ -30,6 +28,7 @@ struct git_reflog_entry { struct git_reflog { git_refdb *db; char *ref_name; + git_oid_t oid_type; git_vector entries; }; diff --git a/src/libgit2/refs.c b/src/libgit2/refs.c index 5c875b95b..8e4abaccc 100644 --- a/src/libgit2/refs.c +++ b/src/libgit2/refs.c @@ -86,6 +86,8 @@ git_reference *git_reference__alloc( if (peel != NULL) git_oid_cpy(&ref->peel, peel); + else + git_oid_clear(&ref->peel, GIT_OID_SHA1); return ref; } diff --git a/src/libgit2/remote.c b/src/libgit2/remote.c index 3d0593712..c3e2a324d 100644 --- a/src/libgit2/remote.c +++ b/src/libgit2/remote.c @@ -17,6 +17,7 @@ #include "fetchhead.h" #include "push.h" #include "proxy.h" +#include "strarray.h" #include "git2/config.h" #include "git2/types.h" @@ -1026,6 +1027,24 @@ int git_remote_capabilities(unsigned int *out, git_remote *remote) return remote->transport->capabilities(out, remote->transport); } +int git_remote_oid_type(git_oid_t *out, git_remote *remote) +{ + GIT_ASSERT_ARG(remote); + + if (!remote->transport) { + git_error_set(GIT_ERROR_NET, "this remote has never connected"); + *out = 0; + return -1; + } + +#ifdef GIT_EXPERIMENTAL_SHA256 + return remote->transport->oid_type(out, remote->transport); +#else + *out = GIT_OID_SHA1; + return 0; +#endif +} + static int lookup_config(char **out, git_config *cfg, const char *name) { git_config_entry *ce = NULL; @@ -1225,24 +1244,6 @@ static int ls_to_vector(git_vector *out, git_remote *remote) return 0; } -#define copy_opts(out, in) \ - if (in) { \ - (out)->callbacks = (in)->callbacks; \ - (out)->proxy_opts = (in)->proxy_opts; \ - (out)->custom_headers = (in)->custom_headers; \ - (out)->follow_redirects = (in)->follow_redirects; \ - } - -GIT_INLINE(int) connect_opts_from_fetch_opts( - git_remote_connect_options *out, - git_remote *remote, - const git_fetch_options *fetch_opts) -{ - git_remote_connect_options tmp = GIT_REMOTE_CONNECT_OPTIONS_INIT; - copy_opts(&tmp, fetch_opts); - return git_remote_connect_options_normalize(out, remote->repo, &tmp); -} - static int connect_or_reset_options( git_remote *remote, int direction, @@ -1330,7 +1331,8 @@ int git_remote_download( return -1; } - if (connect_opts_from_fetch_opts(&connect_opts, remote, opts) < 0) + if (git_remote_connect_options__from_fetch_opts(&connect_opts, + remote, opts) < 0) return -1; if ((error = connect_or_reset_options(remote, GIT_DIRECTION_FETCH, &connect_opts)) < 0) @@ -1350,6 +1352,8 @@ int git_remote_fetch( bool prune = false; git_str reflog_msg_buf = GIT_STR_INIT; git_remote_connect_options connect_opts = GIT_REMOTE_CONNECT_OPTIONS_INIT; + unsigned int capabilities; + git_oid_t oid_type; GIT_ASSERT_ARG(remote); @@ -1358,7 +1362,8 @@ int git_remote_fetch( return -1; } - if (connect_opts_from_fetch_opts(&connect_opts, remote, opts) < 0) + if (git_remote_connect_options__from_fetch_opts(&connect_opts, + remote, opts) < 0) return -1; if ((error = connect_or_reset_options(remote, GIT_DIRECTION_FETCH, &connect_opts)) < 0) @@ -1369,6 +1374,10 @@ int git_remote_fetch( tagopt = opts->download_tags; } + if ((error = git_remote_capabilities(&capabilities, remote)) < 0 || + (error = git_remote_oid_type(&oid_type, remote)) < 0) + return error; + /* Connect and download everything */ error = git_remote__download(remote, refspecs, opts); @@ -1622,7 +1631,7 @@ int git_remote_prune(git_remote *remote, const git_remote_callbacks *callbacks) const git_refspec *spec; const char *refname; int error; - git_oid zero_id = {{ 0 }}; + git_oid zero_id = GIT_OID_SHA1_ZERO; if (callbacks) GIT_ERROR_CHECK_VERSION(callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks"); @@ -1724,7 +1733,7 @@ static int update_ref( const git_remote_callbacks *callbacks) { git_reference *ref; - git_oid old_id; + git_oid old_id = GIT_OID_SHA1_ZERO; int error; error = git_reference_name_to_id(&old_id, remote->repo, ref_name); @@ -1830,7 +1839,7 @@ static int update_one_tip( } if (error == GIT_ENOTFOUND) { - memset(&old, 0, sizeof(git_oid)); + git_oid_clear(&old, GIT_OID_SHA1); error = 0; if (autotag && (error = git_vector_insert(update_heads, head)) < 0) @@ -1892,10 +1901,10 @@ static int update_tips_for_spec( } /* Handle specified oid sources */ - if (git_oid__is_hexstr(spec->src)) { + if (git_oid__is_hexstr(spec->src, GIT_OID_SHA1)) { git_oid id; - if ((error = git_oid_fromstr(&id, spec->src)) < 0) + if ((error = git_oid__fromstr(&id, spec->src, GIT_OID_SHA1)) < 0) goto on_error; if (spec->dst && @@ -2896,16 +2905,6 @@ done: return error; } -GIT_INLINE(int) connect_opts_from_push_opts( - git_remote_connect_options *out, - git_remote *remote, - const git_push_options *push_opts) -{ - git_remote_connect_options tmp = GIT_REMOTE_CONNECT_OPTIONS_INIT; - copy_opts(&tmp, push_opts); - return git_remote_connect_options_normalize(out, remote->repo, &tmp); -} - int git_remote_upload( git_remote *remote, const git_strarray *refspecs, @@ -2924,7 +2923,8 @@ int git_remote_upload( return -1; } - if ((error = connect_opts_from_push_opts(&connect_opts, remote, opts)) < 0) + if ((error = git_remote_connect_options__from_push_opts( + &connect_opts, remote, opts)) < 0) goto cleanup; if ((error = connect_or_reset_options(remote, GIT_DIRECTION_PUSH, &connect_opts)) < 0) @@ -2985,7 +2985,8 @@ int git_remote_push( return -1; } - if (connect_opts_from_push_opts(&connect_opts, remote, opts) < 0) + if (git_remote_connect_options__from_push_opts(&connect_opts, + remote, opts) < 0) return -1; if ((error = git_remote_upload(remote, refspecs, opts)) < 0) diff --git a/src/libgit2/remote.h b/src/libgit2/remote.h index 41ee58e0f..676b3c2ab 100644 --- a/src/libgit2/remote.h +++ b/src/libgit2/remote.h @@ -17,6 +17,7 @@ #include "refspec.h" #include "vector.h" #include "net.h" +#include "proxy.h" #define GIT_REMOTE_ORIGIN "origin" @@ -56,5 +57,44 @@ int git_remote_connect_options_normalize( const git_remote_connect_options *src); int git_remote_capabilities(unsigned int *out, git_remote *remote); +int git_remote_oid_type(git_oid_t *out, git_remote *remote); + + +#define git_remote_connect_options__copy_opts(out, in) \ + if (in) { \ + (out)->callbacks = (in)->callbacks; \ + (out)->proxy_opts = (in)->proxy_opts; \ + (out)->custom_headers = (in)->custom_headers; \ + (out)->follow_redirects = (in)->follow_redirects; \ + } + +GIT_INLINE(int) git_remote_connect_options__from_fetch_opts( + git_remote_connect_options *out, + git_remote *remote, + const git_fetch_options *fetch_opts) +{ + git_remote_connect_options tmp = GIT_REMOTE_CONNECT_OPTIONS_INIT; + git_remote_connect_options__copy_opts(&tmp, fetch_opts); + return git_remote_connect_options_normalize(out, remote->repo, &tmp); +} + +GIT_INLINE(int) git_remote_connect_options__from_push_opts( + git_remote_connect_options *out, + git_remote *remote, + const git_push_options *push_opts) +{ + git_remote_connect_options tmp = GIT_REMOTE_CONNECT_OPTIONS_INIT; + git_remote_connect_options__copy_opts(&tmp, push_opts); + return git_remote_connect_options_normalize(out, remote->repo, &tmp); +} + +#undef git_remote_connect_options__copy_opts + +GIT_INLINE(void) git_remote_connect_options__dispose( + git_remote_connect_options *opts) +{ + git_proxy_options_dispose(&opts->proxy_opts); + git_strarray_dispose(&opts->custom_headers); +} #endif diff --git a/src/libgit2/repository.c b/src/libgit2/repository.c index f761b5f32..8c41167a1 100644 --- a/src/libgit2/repository.c +++ b/src/libgit2/repository.c @@ -67,6 +67,7 @@ static const struct { static int check_repositoryformatversion(int *version, git_config *config); static int check_extensions(git_config *config, int version); static int load_global_config(git_config **config); +static int load_objectformat(git_repository *repo, git_config *config); #define GIT_COMMONDIR_FILE "commondir" #define GIT_GITDIR_FILE "gitdir" @@ -75,8 +76,8 @@ static int load_global_config(git_config **config); #define GIT_BRANCH_DEFAULT "master" -#define GIT_REPO_VERSION 0 -#define GIT_REPO_MAX_VERSION 1 +#define GIT_REPO_VERSION_DEFAULT 0 +#define GIT_REPO_VERSION_MAX 1 git_str git_repository__reserved_names_win32[] = { { DOT_GIT, 0, CONST_STRLEN(DOT_GIT) }, @@ -240,7 +241,7 @@ GIT_INLINE(int) validate_repo_path(git_str *path) */ static size_t suffix_len = CONST_STRLEN("objects/pack/pack-.pack.lock") + - GIT_OID_HEXSZ; + GIT_OID_MAX_HEXSIZE; return git_fs_path_validate_str_length_with_suffix( path, suffix_len); @@ -495,12 +496,47 @@ static int validate_ownership_cb(const git_config_entry *entry, void *payload) { validate_ownership_data *data = payload; - if (strcmp(entry->value, "") == 0) + if (strcmp(entry->value, "") == 0) { *data->is_safe = false; - - if (git_fs_path_prettify_dir(&data->tmp, entry->value, NULL) == 0 && - strcmp(data->tmp.ptr, data->repo_path) == 0) + } else if (strcmp(entry->value, "*") == 0) { *data->is_safe = true; + } else { + const char *test_path = entry->value; + +#ifdef GIT_WIN32 + /* + * Git for Windows does some truly bizarre things with + * paths that start with a forward slash; and expects you + * to escape that with `%(prefix)`. This syntax generally + * means to add the prefix that Git was installed to -- eg + * `/usr/local` -- unless it's an absolute path, in which + * case the leading `%(prefix)/` is just removed. And Git + * for Windows expects you to use this syntax for absolute + * Unix-style paths (in "Git Bash" or Windows Subsystem for + * Linux). + * + * Worse, the behavior used to be that a leading `/` was + * not absolute. It would indicate that Git for Windows + * should add the prefix. So `//` is required for absolute + * Unix-style paths. Yes, this is truly horrifying. + * + * Emulate that behavior, I guess, but only for absolute + * paths. We won't deal with the Git install prefix. Also, + * give WSL users an escape hatch where they don't have to + * think about this and can use the literal path that the + * filesystem APIs provide (`//wsl.localhost/...`). + */ + if (strncmp(test_path, "%(prefix)//", strlen("%(prefix)//")) == 0) + test_path += strlen("%(prefix)/"); + else if (strncmp(test_path, "//", 2) == 0 && + strncmp(test_path, "//wsl.localhost/", strlen("//wsl.localhost/")) != 0) + test_path++; +#endif + + if (git_fs_path_prettify_dir(&data->tmp, test_path, NULL) == 0 && + strcmp(data->tmp.ptr, data->repo_path) == 0) + *data->is_safe = true; + } return 0; } @@ -521,6 +557,9 @@ static int validate_ownership_config(bool *is_safe, const char *path) validate_ownership_cb, &ownership_data); + if (error == GIT_ENOTFOUND) + error = 0; + git_config_free(config); git_str_dispose(&ownership_data.tmp); @@ -541,6 +580,9 @@ static int validate_ownership_path(bool *is_safe, const char *path) if (error == GIT_ENOTFOUND) { *is_safe = true; error = 0; + } else if (error == GIT_EINVALID) { + *is_safe = false; + error = 0; } return error; @@ -727,6 +769,43 @@ out: return error; } +static int obtain_config_and_set_oid_type( + git_config **config_ptr, + git_repository *repo) +{ + int error; + git_config *config = NULL; + int version = 0; + + /* + * We'd like to have the config, but git doesn't particularly + * care if it's not there, so we need to deal with that. + */ + + error = git_repository_config_snapshot(&config, repo); + if (error < 0 && error != GIT_ENOTFOUND) + goto out; + + if (config && + (error = check_repositoryformatversion(&version, config)) < 0) + goto out; + + if ((error = check_extensions(config, version)) < 0) + goto out; + + if (version > 0) { + if ((error = load_objectformat(repo, config)) < 0) + goto out; + } else { + repo->oid_type = GIT_OID_SHA1; + } + +out: + *config_ptr = config; + + return error; +} + int git_repository_open_bare( git_repository **repo_ptr, const char *bare_path) @@ -735,6 +814,7 @@ int git_repository_open_bare( git_repository *repo = NULL; bool is_valid; int error; + git_config *config; if ((error = git_fs_path_prettify_dir(&path, bare_path, NULL)) < 0 || (error = is_valid_repository_path(&is_valid, &path, &common_path)) < 0) @@ -760,8 +840,15 @@ int git_repository_open_bare( repo->is_worktree = 0; repo->workdir = NULL; + if ((error = obtain_config_and_set_oid_type(&config, repo)) < 0) + goto cleanup; + *repo_ptr = repo; - return 0; + +cleanup: + git_config_free(config); + + return error; } static int _git_repository_open_ext_from_env( @@ -843,7 +930,7 @@ static int _git_repository_open_ext_from_env( else if (error < 0) goto error; else { - error = git_odb_open(&odb, git_str_cstr(&object_dir_buf)); + error = git_odb__open(&odb, git_str_cstr(&object_dir_buf), NULL); if (error < 0) goto error; } @@ -968,7 +1055,6 @@ int git_repository_open_ext( gitlink = GIT_STR_INIT, commondir = GIT_STR_INIT; git_repository *repo = NULL; git_config *config = NULL; - int version = 0; if (flags & GIT_REPOSITORY_OPEN_FROM_ENV) return _git_repository_open_ext_from_env(repo_ptr, start_path); @@ -1001,19 +1087,8 @@ int git_repository_open_ext( goto cleanup; repo->is_worktree = is_worktree; - /* - * We'd like to have the config, but git doesn't particularly - * care if it's not there, so we need to deal with that. - */ - - error = git_repository_config_snapshot(&config, repo); - if (error < 0 && error != GIT_ENOTFOUND) - goto cleanup; - - if (config && (error = check_repositoryformatversion(&version, config)) < 0) - goto cleanup; - - if ((error = check_extensions(config, version)) < 0) + error = obtain_config_and_set_oid_type(&config, repo); + if (error < 0) goto cleanup; if ((flags & GIT_REPOSITORY_OPEN_BARE) != 0) { @@ -1264,11 +1339,14 @@ int git_repository_odb__weakptr(git_odb **out, git_repository *repo) *out = git_atomic_load(repo->_odb); if (*out == NULL) { git_str odb_path = GIT_STR_INIT; + git_odb_options odb_opts = GIT_ODB_OPTIONS_INIT; git_odb *odb; + odb_opts.oid_type = repo->oid_type; + if ((error = git_repository__item_path(&odb_path, repo, GIT_REPOSITORY_ITEM_OBJECTS)) < 0 || - (error = git_odb_new(&odb)) < 0) + (error = git_odb__new(&odb, &odb_opts)) < 0) return error; GIT_REFCOUNT_OWN(odb, repo); @@ -1526,6 +1604,7 @@ static int check_repositoryformatversion(int *version, git_config *config) int error; error = git_config_get_int32(version, config, "core.repositoryformatversion"); + /* git ignores this if the config variable isn't there */ if (error == GIT_ENOTFOUND) return 0; @@ -1533,10 +1612,15 @@ static int check_repositoryformatversion(int *version, git_config *config) if (error < 0) return -1; - if (GIT_REPO_MAX_VERSION < *version) { + if (*version < 0) { + git_error_set(GIT_ERROR_REPOSITORY, + "invalid repository version %d", *version); + } + + if (GIT_REPO_VERSION_MAX < *version) { git_error_set(GIT_ERROR_REPOSITORY, "unsupported repository version %d; only versions up to %d are supported", - *version, GIT_REPO_MAX_VERSION); + *version, GIT_REPO_VERSION_MAX); return -1; } @@ -1544,7 +1628,8 @@ static int check_repositoryformatversion(int *version, git_config *config) } static const char *builtin_extensions[] = { - "noop" + "noop", + "objectformat" }; static git_vector user_extensions = GIT_VECTOR_INIT; @@ -1608,6 +1693,79 @@ static int check_extensions(git_config *config, int version) return git_config_foreach_match(config, "^extensions\\.", check_valid_extension, NULL); } +static int load_objectformat(git_repository *repo, git_config *config) +{ + git_config_entry *entry = NULL; + int error; + + if ((error = git_config_get_entry(&entry, config, "extensions.objectformat")) < 0) { + if (error == GIT_ENOTFOUND) { + repo->oid_type = GIT_OID_SHA1; + git_error_clear(); + error = 0; + } + + goto done; + } + + if ((repo->oid_type = git_oid_type_fromstr(entry->value)) == 0) { + git_error_set(GIT_ERROR_REPOSITORY, + "unknown object format '%s'", entry->value); + error = GIT_EINVALID; + } + +done: + git_config_entry_free(entry); + return error; +} + +int git_repository__set_objectformat( + git_repository *repo, + git_oid_t oid_type) +{ + git_config *cfg; + + /* + * Older clients do not necessarily understand the + * `objectformat` extension, even when it's set to an + * object format that they understand (SHA1). Do not set + * the objectformat extension unless we're not using the + * default object format. + */ + if (oid_type == GIT_OID_DEFAULT) + return 0; + + if (!git_repository_is_empty(repo) && repo->oid_type != oid_type) { + git_error_set(GIT_ERROR_REPOSITORY, + "cannot change object id type of existing repository"); + return -1; + } + + if (git_repository_config__weakptr(&cfg, repo) < 0) + return -1; + + if (git_config_set_int32(cfg, + "core.repositoryformatversion", 1) < 0 || + git_config_set_string(cfg, "extensions.objectformat", + git_oid_type_name(oid_type)) < 0) + return -1; + + /* + * During repo init, we may create some backends with the + * default oid type. Clear them so that we create them with + * the proper oid type. + */ + if (repo->oid_type != oid_type) { + set_index(repo, NULL); + set_odb(repo, NULL); + set_refdb(repo, NULL); + + repo->oid_type = oid_type; + } + + return 0; +} + int git_repository__extensions(char ***out, size_t *out_len) { git_vector extensions; @@ -1886,19 +2044,21 @@ static int repo_init_config( const char *repo_dir, const char *work_dir, uint32_t flags, - uint32_t mode) + uint32_t mode, + git_oid_t oid_type) { int error = 0; git_str cfg_path = GIT_STR_INIT, worktree_path = GIT_STR_INIT; git_config *config = NULL; bool is_bare = ((flags & GIT_REPOSITORY_INIT_BARE) != 0); bool is_reinit = ((flags & GIT_REPOSITORY_INIT__IS_REINIT) != 0); - int version = 0; + int version = GIT_REPO_VERSION_DEFAULT; if ((error = repo_local_config(&config, &cfg_path, NULL, repo_dir)) < 0) goto cleanup; - if (is_reinit && (error = check_repositoryformatversion(&version, config)) < 0) + if (is_reinit && + (error = check_repositoryformatversion(&version, config)) < 0) goto cleanup; if ((error = check_extensions(config, version)) < 0) @@ -1909,7 +2069,7 @@ static int repo_init_config( goto cleanup; } while (0) SET_REPO_CONFIG(bool, "core.bare", is_bare); - SET_REPO_CONFIG(int32, "core.repositoryformatversion", GIT_REPO_VERSION); + SET_REPO_CONFIG(int32, "core.repositoryformatversion", version); if ((error = repo_init_fs_configs( config, cfg_path.ptr, repo_dir, work_dir, !is_reinit)) < 0) @@ -1942,6 +2102,11 @@ static int repo_init_config( SET_REPO_CONFIG(bool, "receive.denyNonFastforwards", true); } + if (oid_type != GIT_OID_SHA1) { + SET_REPO_CONFIG(int32, "core.repositoryformatversion", 1); + SET_REPO_CONFIG(string, "extensions.objectformat", git_oid_type_name(oid_type)); + } + cleanup: git_str_dispose(&cfg_path); git_str_dispose(&worktree_path); @@ -2422,6 +2587,7 @@ int git_repository_init_ext( common_path = GIT_STR_INIT; const char *wd; bool is_valid; + git_oid_t oid_type = GIT_OID_DEFAULT; int error; GIT_ASSERT_ARG(out); @@ -2430,6 +2596,11 @@ int git_repository_init_ext( GIT_ERROR_CHECK_VERSION(opts, GIT_REPOSITORY_INIT_OPTIONS_VERSION, "git_repository_init_options"); +#ifdef GIT_EXPERIMENTAL_SHA256 + if (opts->oid_type) + oid_type = opts->oid_type; +#endif + if ((error = repo_init_directories(&repo_path, &wd_path, given_repo, opts)) < 0) goto out; @@ -2448,13 +2619,13 @@ int git_repository_init_ext( opts->flags |= GIT_REPOSITORY_INIT__IS_REINIT; - if ((error = repo_init_config(repo_path.ptr, wd, opts->flags, opts->mode)) < 0) + if ((error = repo_init_config(repo_path.ptr, wd, opts->flags, opts->mode, oid_type)) < 0) goto out; /* TODO: reinitialize the templates */ } else { if ((error = repo_init_structure(repo_path.ptr, wd, opts)) < 0 || - (error = repo_init_config(repo_path.ptr, wd, opts->flags, opts->mode)) < 0 || + (error = repo_init_config(repo_path.ptr, wd, opts->flags, opts->mode, oid_type)) < 0 || (error = repo_init_head(repo_path.ptr, opts->initial_head)) < 0) goto out; } @@ -2917,14 +3088,14 @@ int git_repository__set_orig_head(git_repository *repo, const git_oid *orig_head { git_filebuf file = GIT_FILEBUF_INIT; git_str file_path = GIT_STR_INIT; - char orig_head_str[GIT_OID_HEXSZ]; + char orig_head_str[GIT_OID_MAX_HEXSIZE]; int error = 0; git_oid_fmt(orig_head_str, orig_head); if ((error = git_str_joinpath(&file_path, repo->gitdir, GIT_ORIG_HEAD_FILE)) == 0 && (error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_CREATE_LEADING_DIRS, GIT_MERGE_FILE_MODE)) == 0 && - (error = git_filebuf_printf(&file, "%.*s\n", GIT_OID_HEXSZ, orig_head_str)) == 0) + (error = git_filebuf_printf(&file, "%.*s\n", (int)git_oid_hexsize(repo->oid_type), orig_head_str)) == 0) error = git_filebuf_commit(&file); if (error < 0) @@ -3037,7 +3208,7 @@ int git_repository_hashfile( goto cleanup; } - error = git_odb__hashfd_filtered(out, fd, (size_t)len, type, fl); + error = git_odb__hashfd_filtered(out, fd, (size_t)len, type, repo->oid_type, fl); cleanup: if (fd >= 0) @@ -3384,3 +3555,8 @@ int git_repository_submodule_cache_clear(git_repository *repo) repo->submodule_cache = NULL; return error; } + +git_oid_t git_repository_oid_type(git_repository *repo) +{ + return repo ? repo->oid_type : 0; +} diff --git a/src/libgit2/repository.h b/src/libgit2/repository.h index a488f2bf2..75380ae53 100644 --- a/src/libgit2/repository.h +++ b/src/libgit2/repository.h @@ -153,6 +153,7 @@ struct git_repository { unsigned is_bare:1; unsigned is_worktree:1; + git_oid_t oid_type; unsigned int lru_counter; @@ -256,4 +257,12 @@ int git_repository__extensions(char ***out, size_t *out_len); int git_repository__set_extensions(const char **extensions, size_t len); void git_repository__free_extensions(void); +/* + * Set the object format (OID type) for a repository; this will set + * both the configuration and the internal value for the oid type. + */ +int git_repository__set_objectformat( + git_repository *repo, + git_oid_t oid_type); + #endif diff --git a/src/libgit2/reset.c b/src/libgit2/reset.c index e0d942e5e..9574819cb 100644 --- a/src/libgit2/reset.c +++ b/src/libgit2/reset.c @@ -188,9 +188,9 @@ int git_reset( git_reset_t reset_type, const git_checkout_options *checkout_opts) { - char to[GIT_OID_HEXSZ + 1]; + char to[GIT_OID_SHA1_HEXSIZE + 1]; - git_oid_tostr(to, GIT_OID_HEXSZ + 1, git_object_id(target)); + git_oid_tostr(to, GIT_OID_SHA1_HEXSIZE + 1, git_object_id(target)); return reset(repo, target, to, reset_type, checkout_opts); } diff --git a/src/libgit2/revert.c b/src/libgit2/revert.c index d6ab6ae3c..1106dfe2f 100644 --- a/src/libgit2/revert.c +++ b/src/libgit2/revert.c @@ -107,10 +107,10 @@ static int revert_state_cleanup(git_repository *repo) static int revert_seterr(git_commit *commit, const char *fmt) { - char commit_oidstr[GIT_OID_HEXSZ + 1]; + char commit_oidstr[GIT_OID_SHA1_HEXSIZE + 1]; git_oid_fmt(commit_oidstr, git_commit_id(commit)); - commit_oidstr[GIT_OID_HEXSZ] = '\0'; + commit_oidstr[GIT_OID_SHA1_HEXSIZE] = '\0'; git_error_set(GIT_ERROR_REVERT, fmt, commit_oidstr); @@ -176,7 +176,7 @@ int git_revert( git_revert_options opts; git_reference *our_ref = NULL; git_commit *our_commit = NULL; - char commit_oidstr[GIT_OID_HEXSZ + 1]; + char commit_oidstr[GIT_OID_SHA1_HEXSIZE + 1]; const char *commit_msg; git_str their_label = GIT_STR_INIT; git_index *index = NULL; @@ -192,7 +192,7 @@ int git_revert( return error; git_oid_fmt(commit_oidstr, git_commit_id(commit)); - commit_oidstr[GIT_OID_HEXSZ] = '\0'; + commit_oidstr[GIT_OID_SHA1_HEXSIZE] = '\0'; if ((commit_msg = git_commit_summary(commit)) == NULL) { error = -1; diff --git a/src/libgit2/revparse.c b/src/libgit2/revparse.c index 9bc28e9fc..964afe378 100644 --- a/src/libgit2/revparse.c +++ b/src/libgit2/revparse.c @@ -15,21 +15,28 @@ #include "git2.h" -static int maybe_sha_or_abbrev(git_object **out, git_repository *repo, const char *spec, size_t speclen) +static int maybe_sha_or_abbrev( + git_object **out, + git_repository *repo, + const char *spec, + size_t speclen) { git_oid oid; - if (git_oid_fromstrn(&oid, spec, speclen) < 0) + if (git_oid__fromstrn(&oid, spec, speclen, repo->oid_type) < 0) return GIT_ENOTFOUND; return git_object_lookup_prefix(out, repo, &oid, speclen, GIT_OBJECT_ANY); } -static int maybe_sha(git_object **out, git_repository *repo, const char *spec) +static int maybe_sha( + git_object **out, + git_repository *repo, + const char *spec) { size_t speclen = strlen(spec); - if (speclen != GIT_OID_HEXSZ) + if (speclen != git_oid_hexsize(repo->oid_type)) return GIT_ENOTFOUND; return maybe_sha_or_abbrev(out, repo, spec, speclen); @@ -110,8 +117,8 @@ static int revparse_lookup_object( if (error != GIT_ENOTFOUND) return error; - if ((strlen(spec) < GIT_OID_HEXSZ) && - ((error = maybe_abbrev(object_out, repo, spec)) != GIT_ENOTFOUND)) + if ((strlen(spec) < git_oid_hexsize(repo->oid_type)) && + ((error = maybe_abbrev(object_out, repo, spec)) != GIT_ENOTFOUND)) return error; if ((error = maybe_describe(object_out, repo, spec)) != GIT_ENOTFOUND) @@ -268,7 +275,16 @@ static int retrieve_revobject_from_reflog(git_object **out, git_reference **base int error = -1; if (*base_ref == NULL) { - if ((error = git_reference_dwim(&ref, repo, identifier)) < 0) + /* + * When HEAD@{n} is specified, do not use dwim, which would resolve the + * reference (to the current branch that HEAD is pointing to). + */ + if (position > 0 && strcmp(identifier, GIT_HEAD_FILE) == 0) + error = git_reference_lookup(&ref, repo, GIT_HEAD_FILE); + else + error = git_reference_dwim(&ref, repo, identifier); + + if (error < 0) return error; } else { ref = *base_ref; diff --git a/src/libgit2/revwalk.c b/src/libgit2/revwalk.c index 553e0497a..3269d9279 100644 --- a/src/libgit2/revwalk.c +++ b/src/libgit2/revwalk.c @@ -121,8 +121,12 @@ int git_revwalk__push_ref(git_revwalk *walk, const char *refname, const git_revw { git_oid oid; - if (git_reference_name_to_id(&oid, walk->repo, refname) < 0) + int error = git_reference_name_to_id(&oid, walk->repo, refname); + if (opts->from_glob && (error == GIT_ENOTFOUND || error == GIT_EINVALIDSPEC || error == GIT_EPEEL)) { + return 0; + } else if (error < 0) { return -1; + } return git_revwalk__push_commit(walk, &oid, opts); } diff --git a/src/libgit2/stash.c b/src/libgit2/stash.c index 5fc01ac36..319ae3a3f 100644 --- a/src/libgit2/stash.c +++ b/src/libgit2/stash.c @@ -25,6 +25,7 @@ #include "merge.h" #include "diff.h" #include "diff_generate.h" +#include "strarray.h" static int create_error(int error, const char *msg) { @@ -193,6 +194,30 @@ static int stash_to_index( return git_index_add(index, &entry); } +static int stash_update_index_from_paths( + git_repository *repo, + git_index *index, + const git_strarray *paths) +{ + unsigned int status_flags; + size_t i; + int error = 0; + + for (i = 0; i < paths->count; i++) { + git_status_file(&status_flags, repo, paths->strings[i]); + + if (status_flags & (GIT_STATUS_WT_DELETED | GIT_STATUS_INDEX_DELETED)) { + if ((error = git_index_remove(index, paths->strings[i], 0)) < 0) + return error; + } else { + if ((error = stash_to_index(repo, index, paths->strings[i])) < 0) + return error; + } + } + + return error; +} + static int stash_update_index_from_diff( git_repository *repo, git_index *index, @@ -388,6 +413,66 @@ cleanup: return error; } +static int build_stash_commit_from_tree( + git_oid *w_commit_oid, + git_repository *repo, + const git_signature *stasher, + const char *message, + git_commit *i_commit, + git_commit *b_commit, + git_commit *u_commit, + const git_tree *tree) +{ + const git_commit *parents[] = { NULL, NULL, NULL }; + + parents[0] = b_commit; + parents[1] = i_commit; + parents[2] = u_commit; + + return git_commit_create( + w_commit_oid, + repo, + NULL, + stasher, + stasher, + NULL, + message, + tree, + u_commit ? 3 : 2, + parents); +} + +static int build_stash_commit_from_index( + git_oid *w_commit_oid, + git_repository *repo, + const git_signature *stasher, + const char *message, + git_commit *i_commit, + git_commit *b_commit, + git_commit *u_commit, + git_index *index) +{ + git_tree *tree; + int error; + + if ((error = build_tree_from_index(&tree, repo, index)) < 0) + goto cleanup; + + error = build_stash_commit_from_tree( + w_commit_oid, + repo, + stasher, + message, + i_commit, + b_commit, + u_commit, + tree); + +cleanup: + git_tree_free(tree); + return error; +} + static int commit_worktree( git_oid *w_commit_oid, git_repository *repo, @@ -397,15 +482,10 @@ static int commit_worktree( git_commit *b_commit, git_commit *u_commit) { - const git_commit *parents[] = { NULL, NULL, NULL }; git_index *i_index = NULL, *r_index = NULL; git_tree *w_tree = NULL; int error = 0, ignorecase; - parents[0] = b_commit; - parents[1] = i_commit; - parents[2] = u_commit; - if ((error = git_repository_index(&r_index, repo) < 0) || (error = git_index_new(&i_index)) < 0 || (error = git_index__fill(i_index, &r_index->entries) < 0) || @@ -417,17 +497,16 @@ static int commit_worktree( if ((error = build_workdir_tree(&w_tree, repo, i_index, b_commit)) < 0) goto cleanup; - error = git_commit_create( + error = build_stash_commit_from_tree( w_commit_oid, repo, - NULL, stasher, - stasher, - NULL, message, - w_tree, - u_commit ? 3 : 2, - parents); + i_commit, + b_commit, + u_commit, + w_tree + ); cleanup: git_tree_free(w_tree); @@ -520,6 +599,54 @@ static int ensure_there_are_changes_to_stash(git_repository *repo, uint32_t flag return error; } +static int has_changes_cb( + const char *path, + unsigned int status, + void *payload) +{ + GIT_UNUSED(path); + GIT_UNUSED(status); + GIT_UNUSED(payload); + + if (status == GIT_STATUS_CURRENT) + return GIT_ENOTFOUND; + + return 0; +} + +static int ensure_there_are_changes_to_stash_paths( + git_repository *repo, + uint32_t flags, + const git_strarray *paths) +{ + int error; + git_status_options opts = GIT_STATUS_OPTIONS_INIT; + + opts.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR; + opts.flags = GIT_STATUS_OPT_EXCLUDE_SUBMODULES | + GIT_STATUS_OPT_INCLUDE_UNMODIFIED | + GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH; + + if (flags & GIT_STASH_INCLUDE_UNTRACKED) + opts.flags |= GIT_STATUS_OPT_INCLUDE_UNTRACKED | + GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS; + + if (flags & GIT_STASH_INCLUDE_IGNORED) + opts.flags |= GIT_STATUS_OPT_INCLUDE_IGNORED | + GIT_STATUS_OPT_RECURSE_IGNORED_DIRS; + + git_strarray_copy(&opts.pathspec, paths); + + error = git_status_foreach_ext(repo, &opts, has_changes_cb, NULL); + + git_strarray_dispose(&opts.pathspec); + + if (error == GIT_ENOTFOUND) + return create_error(GIT_ENOTFOUND, "one of the files does not have any changes to stash."); + + return error; +} + static int reset_index_and_workdir(git_repository *repo, git_commit *commit, uint32_t flags) { git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; @@ -540,14 +667,36 @@ int git_stash_save( const char *message, uint32_t flags) { - git_index *index = NULL; + git_stash_save_options opts = GIT_STASH_SAVE_OPTIONS_INIT; + + GIT_ASSERT_ARG(stasher); + + opts.stasher = stasher; + opts.message = message; + opts.flags = flags; + + return git_stash_save_with_opts(out, repo, &opts); +} + +int git_stash_save_with_opts( + git_oid *out, + git_repository *repo, + const git_stash_save_options *opts) +{ + git_index *index = NULL, *paths_index = NULL; git_commit *b_commit = NULL, *i_commit = NULL, *u_commit = NULL; git_str msg = GIT_STR_INIT; + git_tree *tree = NULL; + git_reference *head = NULL; + bool has_paths = false; + int error; GIT_ASSERT_ARG(out); GIT_ASSERT_ARG(repo); - GIT_ASSERT_ARG(stasher); + GIT_ASSERT_ARG(opts && opts->stasher); + + has_paths = opts->paths.count > 0; if ((error = git_repository__ensure_not_bare(repo, "stash save")) < 0) return error; @@ -555,44 +704,63 @@ int git_stash_save( if ((error = retrieve_base_commit_and_message(&b_commit, &msg, repo)) < 0) goto cleanup; - if ((error = ensure_there_are_changes_to_stash(repo, flags)) < 0) + if (!has_paths && + (error = ensure_there_are_changes_to_stash(repo, opts->flags)) < 0) + goto cleanup; + else if (has_paths && + (error = ensure_there_are_changes_to_stash_paths( + repo, opts->flags, &opts->paths)) < 0) goto cleanup; if ((error = git_repository_index(&index, repo)) < 0) goto cleanup; - if ((error = commit_index(&i_commit, repo, index, stasher, + if ((error = commit_index(&i_commit, repo, index, opts->stasher, git_str_cstr(&msg), b_commit)) < 0) goto cleanup; - if ((flags & (GIT_STASH_INCLUDE_UNTRACKED | GIT_STASH_INCLUDE_IGNORED)) && - (error = commit_untracked(&u_commit, repo, stasher, - git_str_cstr(&msg), i_commit, flags)) < 0) + if ((opts->flags & (GIT_STASH_INCLUDE_UNTRACKED | GIT_STASH_INCLUDE_IGNORED)) && + (error = commit_untracked(&u_commit, repo, opts->stasher, + git_str_cstr(&msg), i_commit, opts->flags)) < 0) goto cleanup; - if ((error = prepare_worktree_commit_message(&msg, message)) < 0) + if ((error = prepare_worktree_commit_message(&msg, opts->message)) < 0) goto cleanup; - if ((error = commit_worktree(out, repo, stasher, git_str_cstr(&msg), - i_commit, b_commit, u_commit)) < 0) - goto cleanup; + if (!has_paths) { + if ((error = commit_worktree(out, repo, opts->stasher, git_str_cstr(&msg), + i_commit, b_commit, u_commit)) < 0) + goto cleanup; + } else { + if ((error = git_index_new(&paths_index)) < 0 || + (error = retrieve_head(&head, repo)) < 0 || + (error = git_reference_peel((git_object**)&tree, head, GIT_OBJECT_TREE)) < 0 || + (error = git_index_read_tree(paths_index, tree)) < 0 || + (error = stash_update_index_from_paths(repo, paths_index, &opts->paths)) < 0 || + (error = build_stash_commit_from_index(out, repo, opts->stasher, git_str_cstr(&msg), + i_commit, b_commit, u_commit, paths_index)) < 0) + goto cleanup; + } git_str_rtrim(&msg); if ((error = update_reflog(out, repo, git_str_cstr(&msg))) < 0) goto cleanup; - if ((error = reset_index_and_workdir(repo, (flags & GIT_STASH_KEEP_INDEX) ? i_commit : b_commit, - flags)) < 0) + if (!(opts->flags & GIT_STASH_KEEP_ALL) && + (error = reset_index_and_workdir(repo, + (opts->flags & GIT_STASH_KEEP_INDEX) ? i_commit : b_commit,opts->flags)) < 0) goto cleanup; cleanup: - git_str_dispose(&msg); git_commit_free(i_commit); git_commit_free(b_commit); git_commit_free(u_commit); + git_tree_free(tree); + git_reference_free(head); git_index_free(index); + git_index_free(paths_index); return error; } @@ -777,6 +945,13 @@ int git_stash_apply_options_init(git_stash_apply_options *opts, unsigned int ver return 0; } +int git_stash_save_options_init(git_stash_save_options *opts, unsigned int version) +{ + GIT_INIT_STRUCTURE_FROM_TEMPLATE( + opts, version, git_stash_save_options, GIT_STASH_SAVE_OPTIONS_INIT); + return 0; +} + #ifndef GIT_DEPRECATE_HARD int git_stash_apply_init_options(git_stash_apply_options *opts, unsigned int version) { diff --git a/src/libgit2/strarray.c b/src/libgit2/strarray.c index 2f9b77cc2..25e75f02a 100644 --- a/src/libgit2/strarray.c +++ b/src/libgit2/strarray.c @@ -8,6 +8,7 @@ #include "util.h" #include "common.h" +#include "strarray.h" int git_strarray_copy(git_strarray *tgt, const git_strarray *src) { diff --git a/src/libgit2/strarray.h b/src/libgit2/strarray.h new file mode 100644 index 000000000..198480535 --- /dev/null +++ b/src/libgit2/strarray.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ +#ifndef INCLUDE_strarray_h__ +#define INCLUDE_strarray_h__ + +#include "common.h" +#include "git2/strarray.h" + +/** + * Copy a string array object from source to target. + * + * Note: target is overwritten and hence should be empty, otherwise its + * contents are leaked. Call git_strarray_free() if necessary. + * + * @param tgt target + * @param src source + * @return 0 on success, < 0 on allocation failure + */ +extern int git_strarray_copy(git_strarray *tgt, const git_strarray *src); + +#endif diff --git a/src/libgit2/streams/openssl.c b/src/libgit2/streams/openssl.c index 89c96780c..5e0e2c939 100644 --- a/src/libgit2/streams/openssl.c +++ b/src/libgit2/streams/openssl.c @@ -198,7 +198,7 @@ static int openssl_ensure_initialized(void) if ((error = git_openssl_stream_dynamic_init()) == 0) error = openssl_init(); - openssl_initialized = true; + openssl_initialized = !error; } error |= git_mutex_unlock(&openssl_mutex); diff --git a/src/libgit2/streams/openssl_dynamic.c b/src/libgit2/streams/openssl_dynamic.c index da16b6ed7..222c1099d 100644 --- a/src/libgit2/streams/openssl_dynamic.c +++ b/src/libgit2/streams/openssl_dynamic.c @@ -91,7 +91,7 @@ int (*sk_num)(const void *sk); void *(*sk_value)(const void *sk, int i); void (*sk_free)(void *sk); -void *openssl_handle; +static void *openssl_handle; GIT_INLINE(void *) openssl_sym(int *err, const char *name, bool required) { @@ -125,7 +125,8 @@ int git_openssl_stream_dynamic_init(void) (openssl_handle = dlopen("libssl.1.1.dylib", RTLD_NOW)) == NULL && (openssl_handle = dlopen("libssl.so.1.0.0", RTLD_NOW)) == NULL && (openssl_handle = dlopen("libssl.1.0.0.dylib", RTLD_NOW)) == NULL && - (openssl_handle = dlopen("libssl.so.10", RTLD_NOW)) == NULL) { + (openssl_handle = dlopen("libssl.so.10", RTLD_NOW)) == NULL && + (openssl_handle = dlopen("libssl.so.3", RTLD_NOW)) == NULL) { git_error_set(GIT_ERROR_SSL, "could not load ssl libraries"); return -1; } @@ -175,7 +176,6 @@ int git_openssl_stream_dynamic_init(void) SSL_connect = (int (*)(SSL *))openssl_sym(&err, "SSL_connect", true); SSL_ctrl = (long (*)(SSL *, int, long, void *))openssl_sym(&err, "SSL_ctrl", true); - SSL_get_peer_certificate = (X509 *(*)(const SSL *))openssl_sym(&err, "SSL_get_peer_certificate", true); SSL_library_init = (int (*)(void))openssl_sym(&err, "SSL_library_init", false); SSL_free = (void (*)(SSL *))openssl_sym(&err, "SSL_free", true); SSL_get_error = (int (*)(SSL *, int))openssl_sym(&err, "SSL_get_error", true); @@ -187,6 +187,10 @@ int git_openssl_stream_dynamic_init(void) SSL_shutdown = (int (*)(SSL *ssl))openssl_sym(&err, "SSL_shutdown", true); SSL_write = (int (*)(SSL *, const void *, int))openssl_sym(&err, "SSL_write", true); + if (!(SSL_get_peer_certificate = (X509 *(*)(const SSL *))openssl_sym(&err, "SSL_get_peer_certificate", false))) { + SSL_get_peer_certificate = (X509 *(*)(const SSL *))openssl_sym(&err, "SSL_get1_peer_certificate", true); + } + SSL_CTX_ctrl = (long (*)(SSL_CTX *, int, long, void *))openssl_sym(&err, "SSL_CTX_ctrl", true); SSL_CTX_free = (void (*)(SSL_CTX *))openssl_sym(&err, "SSL_CTX_free", true); SSL_CTX_new = (SSL_CTX *(*)(const SSL_METHOD *))openssl_sym(&err, "SSL_CTX_new", true); diff --git a/src/libgit2/streams/socket.c b/src/libgit2/streams/socket.c index 9415fe892..908e8c02f 100644 --- a/src/libgit2/streams/socket.c +++ b/src/libgit2/streams/socket.c @@ -135,9 +135,12 @@ static ssize_t socket_write(git_stream *stream, const char *data, size_t len, in git_socket_stream *st = (git_socket_stream *) stream; ssize_t written; + GIT_ASSERT(flags == 0); + GIT_UNUSED(flags); + errno = 0; - if ((written = p_send(st->s, data, len, flags)) < 0) { + if ((written = p_send(st->s, data, len, 0)) < 0) { net_set_error("error sending data"); return -1; } diff --git a/src/libgit2/submodule.c b/src/libgit2/submodule.c index 0f4f0726c..95ea84fc2 100644 --- a/src/libgit2/submodule.c +++ b/src/libgit2/submodule.c @@ -1338,7 +1338,11 @@ int git_submodule_update(git_submodule *sm, int init, git_submodule_update_optio /* Get the status of the submodule to determine if it is already initialized */ if ((error = git_submodule_status(&submodule_status, sm->repo, sm->name, GIT_SUBMODULE_IGNORE_UNSPECIFIED)) < 0) goto done; - + + /* If the submodule is configured but hasn't been added, skip it */ + if (submodule_status == GIT_SUBMODULE_STATUS_IN_CONFIG) + goto done; + /* * If submodule work dir is not already initialized, check to see * what we need to do (initialize, clone, return error...) @@ -1389,7 +1393,7 @@ int git_submodule_update(git_submodule *sm, int init, git_submodule_update_optio */ clone_options.checkout_opts.checkout_strategy = GIT_CHECKOUT_NONE; - if ((error = git_clone(&sub_repo, submodule_url, sm->path, &clone_options)) < 0 || + if ((error = git_clone__submodule(&sub_repo, submodule_url, sm->path, &clone_options)) < 0 || (error = git_repository_set_head_detached(sub_repo, git_submodule_index_id(sm))) < 0 || (error = git_checkout_head(sub_repo, &update_options.checkout_opts)) != 0) goto done; diff --git a/src/libgit2/sysdir.c b/src/libgit2/sysdir.c index 450cb509b..7838a6789 100644 --- a/src/libgit2/sysdir.c +++ b/src/libgit2/sysdir.c @@ -12,16 +12,262 @@ #include "fs_path.h" #include #if GIT_WIN32 -#include "win32/findfile.h" +# include "fs_path.h" +# include "win32/path_w32.h" +# include "win32/utf-conv.h" #else -#include -#include +# include +# include #endif +#ifdef GIT_WIN32 +# define REG_GITFORWINDOWS_KEY L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Git_is1" +# define REG_GITFORWINDOWS_KEY_WOW64 L"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Git_is1" + +static int expand_win32_path(git_win32_path dest, const wchar_t *src) +{ + DWORD len = ExpandEnvironmentStringsW(src, dest, GIT_WIN_PATH_UTF16); + + if (!len || len > GIT_WIN_PATH_UTF16) + return -1; + + return 0; +} + +static int win32_path_to_utf8(git_str *dest, const wchar_t *src) +{ + git_win32_utf8_path utf8_path; + + if (git_win32_path_to_utf8(utf8_path, src) < 0) { + git_error_set(GIT_ERROR_OS, "unable to convert path to UTF-8"); + return -1; + } + + /* Convert backslashes to forward slashes */ + git_fs_path_mkposix(utf8_path); + + return git_str_sets(dest, utf8_path); +} + +static git_win32_path mock_registry; +static bool mock_registry_set; + +extern int git_win32__set_registry_system_dir(const wchar_t *mock_sysdir) +{ + if (!mock_sysdir) { + mock_registry[0] = L'\0'; + mock_registry_set = false; + } else { + size_t len = wcslen(mock_sysdir); + + if (len > GIT_WIN_PATH_MAX) { + git_error_set(GIT_ERROR_INVALID, "mock path too long"); + return -1; + } + + wcscpy(mock_registry, mock_sysdir); + mock_registry_set = true; + } + + return 0; +} + +static int lookup_registry_key( + git_win32_path out, + const HKEY hive, + const wchar_t* key, + const wchar_t *value) +{ + HKEY hkey; + DWORD type, size; + int error = GIT_ENOTFOUND; + + /* + * Registry data may not be NUL terminated, provide room to do + * it ourselves. + */ + size = (DWORD)((sizeof(git_win32_path) - 1) * sizeof(wchar_t)); + + if (RegOpenKeyExW(hive, key, 0, KEY_READ, &hkey) != 0) + return GIT_ENOTFOUND; + + if (RegQueryValueExW(hkey, value, NULL, &type, (LPBYTE)out, &size) == 0 && + type == REG_SZ && + size > 0 && + size < sizeof(git_win32_path)) { + size_t wsize = size / sizeof(wchar_t); + size_t len = wsize - 1; + + if (out[wsize - 1] != L'\0') { + len = wsize; + out[wsize] = L'\0'; + } + + if (out[len - 1] == L'\\') + out[len - 1] = L'\0'; + + if (_waccess(out, F_OK) == 0) + error = 0; + } + + RegCloseKey(hkey); + return error; +} + +static int find_sysdir_in_registry(git_win32_path out) +{ + if (mock_registry_set) { + if (mock_registry[0] == L'\0') + return GIT_ENOTFOUND; + + wcscpy(out, mock_registry); + return 0; + } + + if (lookup_registry_key(out, HKEY_CURRENT_USER, REG_GITFORWINDOWS_KEY, L"InstallLocation") == 0 || + lookup_registry_key(out, HKEY_CURRENT_USER, REG_GITFORWINDOWS_KEY_WOW64, L"InstallLocation") == 0 || + lookup_registry_key(out, HKEY_LOCAL_MACHINE, REG_GITFORWINDOWS_KEY, L"InstallLocation") == 0 || + lookup_registry_key(out, HKEY_LOCAL_MACHINE, REG_GITFORWINDOWS_KEY_WOW64, L"InstallLocation") == 0) + return 0; + + return GIT_ENOTFOUND; +} + +static int find_sysdir_in_path(git_win32_path out) +{ + size_t out_len; + + if (git_win32_path_find_executable(out, L"git.exe") < 0 && + git_win32_path_find_executable(out, L"git.cmd") < 0) + return GIT_ENOTFOUND; + + out_len = wcslen(out); + + /* Trim the file name */ + if (out_len <= CONST_STRLEN(L"git.exe")) + return GIT_ENOTFOUND; + + out_len -= CONST_STRLEN(L"git.exe"); + + if (out_len && out[out_len - 1] == L'\\') + out_len--; + + /* + * Git for Windows usually places the command in a 'bin' or + * 'cmd' directory, trim that. + */ + if (out_len >= CONST_STRLEN(L"\\bin") && + wcsncmp(&out[out_len - CONST_STRLEN(L"\\bin")], L"\\bin", CONST_STRLEN(L"\\bin")) == 0) + out_len -= CONST_STRLEN(L"\\bin"); + else if (out_len >= CONST_STRLEN(L"\\cmd") && + wcsncmp(&out[out_len - CONST_STRLEN(L"\\cmd")], L"\\cmd", CONST_STRLEN(L"\\cmd")) == 0) + out_len -= CONST_STRLEN(L"\\cmd"); + + if (!out_len) + return GIT_ENOTFOUND; + + out[out_len] = L'\0'; + return 0; +} + +static int find_win32_dirs( + git_str *out, + const wchar_t* tmpl[]) +{ + git_win32_path path16; + git_str buf = GIT_STR_INIT; + + git_str_clear(out); + + for (; *tmpl != NULL; tmpl++) { + if (!expand_win32_path(path16, *tmpl) && + path16[0] != L'%' && + !_waccess(path16, F_OK)) { + win32_path_to_utf8(&buf, path16); + + if (buf.size) + git_str_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr); + } + } + + git_str_dispose(&buf); + + return (git_str_oom(out) ? -1 : 0); +} + +static int append_subdir(git_str *out, git_str *path, const char *subdir) +{ + static const char* architecture_roots[] = { + "", + "mingw64", + "mingw32", + NULL + }; + const char **root; + size_t orig_path_len = path->size; + + for (root = architecture_roots; *root; root++) { + if ((*root[0] && git_str_joinpath(path, path->ptr, *root) < 0) || + git_str_joinpath(path, path->ptr, subdir) < 0) + return -1; + + if (git_fs_path_exists(path->ptr) && + git_str_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, path->ptr) < 0) + return -1; + + git_str_truncate(path, orig_path_len); + } + + return 0; +} + +int git_win32__find_system_dirs(git_str *out, const char *subdir) +{ + git_win32_path pathdir, regdir; + git_str path8 = GIT_STR_INIT; + bool has_pathdir, has_regdir; + int error; + + has_pathdir = (find_sysdir_in_path(pathdir) == 0); + has_regdir = (find_sysdir_in_registry(regdir) == 0); + + if (!has_pathdir && !has_regdir) + return 0; + + /* + * Usually the git in the path is the same git in the registry, + * in this case there's no need to duplicate the paths. + */ + if (has_pathdir && has_regdir && wcscmp(pathdir, regdir) == 0) + has_regdir = false; + + if (has_pathdir) { + if ((error = win32_path_to_utf8(&path8, pathdir)) < 0 || + (error = append_subdir(out, &path8, subdir)) < 0) + goto done; + } + + if (has_regdir) { + if ((error = win32_path_to_utf8(&path8, regdir)) < 0 || + (error = append_subdir(out, &path8, subdir)) < 0) + goto done; + } + +done: + git_str_dispose(&path8); + return error; +} +#endif /* WIN32 */ + static int git_sysdir_guess_programdata_dirs(git_str *out) { #ifdef GIT_WIN32 - return git_win32__find_programdata_dirs(out); + static const wchar_t *programdata_tmpls[2] = { + L"%PROGRAMDATA%\\Git", + NULL, + }; + + return find_win32_dirs(out, programdata_tmpls); #else git_str_clear(out); return 0; @@ -75,10 +321,17 @@ out: } #endif -static int git_sysdir_guess_global_dirs(git_str *out) +static int git_sysdir_guess_home_dirs(git_str *out) { #ifdef GIT_WIN32 - return git_win32__find_global_dirs(out); + static const wchar_t *global_tmpls[4] = { + L"%HOME%\\", + L"%HOMEDRIVE%%HOMEPATH%\\", + L"%USERPROFILE%\\", + NULL, + }; + + return find_win32_dirs(out, global_tmpls); #else int error; uid_t uid, euid; @@ -114,10 +367,25 @@ static int git_sysdir_guess_global_dirs(git_str *out) #endif } +static int git_sysdir_guess_global_dirs(git_str *out) +{ + return git_sysdir_guess_home_dirs(out); +} + static int git_sysdir_guess_xdg_dirs(git_str *out) { #ifdef GIT_WIN32 - return git_win32__find_xdg_dirs(out); + static const wchar_t *global_tmpls[7] = { + L"%XDG_CONFIG_HOME%\\git", + L"%APPDATA%\\git", + L"%LOCALAPPDATA%\\git", + L"%HOME%\\.config\\git", + L"%HOMEDRIVE%%HOMEPATH%\\.config\\git", + L"%USERPROFILE%\\.config\\git", + NULL, + }; + + return find_win32_dirs(out, global_tmpls); #else git_str env = GIT_STR_INIT; int error; @@ -171,6 +439,7 @@ static struct git_sysdir__dir git_sysdir__dirs[] = { { GIT_STR_INIT, git_sysdir_guess_xdg_dirs }, { GIT_STR_INIT, git_sysdir_guess_programdata_dirs }, { GIT_STR_INIT, git_sysdir_guess_template_dirs }, + { GIT_STR_INIT, git_sysdir_guess_home_dirs } }; static void git_sysdir_global_shutdown(void) @@ -350,6 +619,12 @@ int git_sysdir_find_template_dir(git_str *path) path, NULL, GIT_SYSDIR_TEMPLATE, "template"); } +int git_sysdir_find_homedir(git_str *path) +{ + return git_sysdir_find_in_dirlist( + path, NULL, GIT_SYSDIR_HOME, "home directory"); +} + int git_sysdir_expand_global_file(git_str *path, const char *filename) { int error; @@ -361,3 +636,15 @@ int git_sysdir_expand_global_file(git_str *path, const char *filename) return error; } + +int git_sysdir_expand_homedir_file(git_str *path, const char *filename) +{ + int error; + + if ((error = git_sysdir_find_homedir(path)) == 0) { + if (filename) + error = git_str_joinpath(path, path->ptr, filename); + } + + return error; +} diff --git a/src/libgit2/sysdir.h b/src/libgit2/sysdir.h index 568f27940..03f59e1de 100644 --- a/src/libgit2/sysdir.h +++ b/src/libgit2/sysdir.h @@ -57,10 +57,22 @@ extern int git_sysdir_find_programdata_file(git_str *path, const char *filename) extern int git_sysdir_find_template_dir(git_str *path); /** - * Expand the name of a "global" file (i.e. one in a user's home - * directory). Unlike `find_global_file` (above), this makes no - * attempt to check for the existence of the file, and is useful if - * you want the full path regardless of existence. + * Find the home directory. On Windows, this will look at the `HOME`, + * `HOMEPATH`, and `USERPROFILE` environment variables (in that order) + * and return the first path that is set and exists. On other systems, + * this will simply return the contents of the `HOME` environment variable. + * + * @param path buffer to write the full path into + * @return 0 if found, GIT_ENOTFOUND if not found, or -1 on other OS error + */ +extern int git_sysdir_find_homedir(git_str *path); + +/** + * Expand the name of a "global" file -- by default inside the user's + * home directory, but can be overridden by the user configuration. + * Unlike `find_global_file` (above), this makes no attempt to check + * for the existence of the file, and is useful if you want the full + * path regardless of existence. * * @param path buffer to write the full path into * @param filename name of file in the home directory @@ -68,13 +80,25 @@ extern int git_sysdir_find_template_dir(git_str *path); */ extern int git_sysdir_expand_global_file(git_str *path, const char *filename); +/** + * Expand the name of a file in the user's home directory. This + * function makes no attempt to check for the existence of the file, + * and is useful if you want the full path regardless of existence. + * + * @param path buffer to write the full path into + * @param filename name of file in the home directory + * @return 0 on success or -1 on error + */ +extern int git_sysdir_expand_homedir_file(git_str *path, const char *filename); + typedef enum { - GIT_SYSDIR_SYSTEM = 0, - GIT_SYSDIR_GLOBAL = 1, - GIT_SYSDIR_XDG = 2, + GIT_SYSDIR_SYSTEM = 0, + GIT_SYSDIR_GLOBAL = 1, + GIT_SYSDIR_XDG = 2, GIT_SYSDIR_PROGRAMDATA = 3, - GIT_SYSDIR_TEMPLATE = 4, - GIT_SYSDIR__MAX = 5 + GIT_SYSDIR_TEMPLATE = 4, + GIT_SYSDIR_HOME = 5, + GIT_SYSDIR__MAX = 6 } git_sysdir_t; /** @@ -110,4 +134,12 @@ extern int git_sysdir_set(git_sysdir_t which, const char *paths); */ extern int git_sysdir_reset(void); +#ifdef GIT_WIN32 +/** Sets the registry system dir to a mock; for testing. */ +extern int git_win32__set_registry_system_dir(const wchar_t *mock_sysdir); + +/** Find the given system dir; for testing. */ +extern int git_win32__find_system_dirs(git_str *out, const char *subdir); +#endif + #endif diff --git a/src/libgit2/tag.c b/src/libgit2/tag.c index 792155a4b..562ec13ea 100644 --- a/src/libgit2/tag.c +++ b/src/libgit2/tag.c @@ -65,7 +65,11 @@ static int tag_error(const char *str) return GIT_EINVALID; } -static int tag_parse(git_tag *tag, const char *buffer, const char *buffer_end) +static int tag_parse( + git_tag *tag, + const char *buffer, + const char *buffer_end, + git_oid_t oid_type) { static const char *tag_types[] = { NULL, "commit\n", "tree\n", "blob\n", "tag\n" @@ -75,7 +79,8 @@ static int tag_parse(git_tag *tag, const char *buffer, const char *buffer_end) unsigned int i; int error; - if (git_oid__parse(&tag->target, &buffer, buffer_end, "object ") < 0) + if (git_object__parse_oid_header(&tag->target, + &buffer, buffer_end, "object ", oid_type) < 0) return tag_error("object field invalid"); if (buffer + 5 >= buffer_end) @@ -160,18 +165,25 @@ static int tag_parse(git_tag *tag, const char *buffer, const char *buffer_end) return 0; } -int git_tag__parse_raw(void *_tag, const char *data, size_t size) +int git_tag__parse_raw( + void *_tag, + const char *data, + size_t size, + git_oid_t oid_type) { - return tag_parse(_tag, data, data + size); + return tag_parse(_tag, data, data + size, oid_type); } -int git_tag__parse(void *_tag, git_odb_object *odb_obj) +int git_tag__parse( + void *_tag, + git_odb_object *odb_obj, + git_oid_t oid_type) { git_tag *tag = _tag; const char *buffer = git_odb_object_data(odb_obj); const char *buffer_end = buffer + git_odb_object_size(odb_obj); - return tag_parse(tag, buffer, buffer_end); + return tag_parse(tag, buffer, buffer_end, oid_type); } static int retrieve_tag_reference( @@ -220,7 +232,9 @@ static int write_tag_annotation( git_str tag = GIT_STR_INIT; git_odb *odb; - git_oid__writebuf(&tag, "object ", git_object_id(target)); + if (git_object__write_oid_header(&tag, "object ", git_object_id(target)) < 0) + goto on_error; + git_str_printf(&tag, "type %s\n", git_object_type2string(git_object_type(target))); git_str_printf(&tag, "tag %s\n", tag_name); git_signature__writebuf(&tag, "tagger ", tagger); @@ -296,8 +310,10 @@ static int git_tag_create__internal( } if (create_tag_annotation) { - if (write_tag_annotation(oid, repo, tag_name, target, tagger, message) < 0) + if (write_tag_annotation(oid, repo, tag_name, target, tagger, message) < 0) { + git_str_dispose(&ref_name); return -1; + } } else git_oid_cpy(oid, git_object_id(target)); @@ -369,7 +385,7 @@ int git_tag_create_from_buffer(git_oid *oid, git_repository *repo, const char *b return -1; /* validate the buffer */ - if (tag_parse(&tag, buffer, buffer + strlen(buffer)) < 0) + if (tag_parse(&tag, buffer, buffer + strlen(buffer), repo->oid_type) < 0) return -1; /* validate the target */ @@ -394,14 +410,17 @@ int git_tag_create_from_buffer(git_oid *oid, git_repository *repo, const char *b /** Ensure the tag name doesn't conflict with an already existing * reference unless overwriting has explicitly been requested **/ if (error == 0 && !allow_ref_overwrite) { + git_str_dispose(&ref_name); git_error_set(GIT_ERROR_TAG, "tag already exists"); return GIT_EEXISTS; } /* write the buffer */ if ((error = git_odb_open_wstream( - &stream, odb, strlen(buffer), GIT_OBJECT_TAG)) < 0) + &stream, odb, strlen(buffer), GIT_OBJECT_TAG)) < 0) { + git_str_dispose(&ref_name); return error; + } if (!(error = git_odb_stream_write(stream, buffer, strlen(buffer)))) error = git_odb_stream_finalize_write(oid, stream); diff --git a/src/libgit2/tag.h b/src/libgit2/tag.h index 76ae1508e..fdaaa463c 100644 --- a/src/libgit2/tag.h +++ b/src/libgit2/tag.h @@ -25,7 +25,7 @@ struct git_tag { }; void git_tag__free(void *tag); -int git_tag__parse(void *tag, git_odb_object *obj); -int git_tag__parse_raw(void *tag, const char *data, size_t size); +int git_tag__parse(void *tag, git_odb_object *obj, git_oid_t oid_type); +int git_tag__parse_raw(void *tag, const char *data, size_t size, git_oid_t oid_type); #endif diff --git a/src/libgit2/threadstate.h b/src/libgit2/threadstate.h index c10f26b59..f9e7ba7bf 100644 --- a/src/libgit2/threadstate.h +++ b/src/libgit2/threadstate.h @@ -13,7 +13,7 @@ typedef struct { git_error *last_error; git_error error_t; git_str error_buf; - char oid_fmt[GIT_OID_HEXSZ+1]; + char oid_fmt[GIT_OID_SHA1_HEXSIZE+1]; } git_threadstate; extern int git_threadstate_global_init(void); diff --git a/src/libgit2/transports/http.c b/src/libgit2/transports/http.c index 7db5582ca..cda76ae61 100644 --- a/src/libgit2/transports/http.c +++ b/src/libgit2/transports/http.c @@ -655,6 +655,7 @@ static int http_action( { http_subtransport *transport = GIT_CONTAINER_OF(t, http_subtransport, parent); git_remote_connect_options *connect_opts = &transport->owner->connect_opts; + git_http_client_options opts = {0}; http_stream *stream; const http_service *service; int error; @@ -683,14 +684,14 @@ static int http_action( stream = git__calloc(sizeof(http_stream), 1); GIT_ERROR_CHECK_ALLOC(stream); - if (!transport->http_client) { - git_http_client_options opts = {0}; - - opts.server_certificate_check_cb = connect_opts->callbacks.certificate_check; - opts.server_certificate_check_payload = connect_opts->callbacks.payload; - opts.proxy_certificate_check_cb = connect_opts->proxy_opts.certificate_check; - opts.proxy_certificate_check_payload = connect_opts->proxy_opts.payload; + opts.server_certificate_check_cb = connect_opts->callbacks.certificate_check; + opts.server_certificate_check_payload = connect_opts->callbacks.payload; + opts.proxy_certificate_check_cb = connect_opts->proxy_opts.certificate_check; + opts.proxy_certificate_check_payload = connect_opts->proxy_opts.payload; + if (transport->http_client) { + git_http_client_set_options(transport->http_client, &opts); + } else { if (git_http_client_new(&transport->http_client, &opts) < 0) return -1; } diff --git a/src/libgit2/transports/httpclient.c b/src/libgit2/transports/httpclient.c index f07923ef2..0ad6cd4dc 100644 --- a/src/libgit2/transports/httpclient.c +++ b/src/libgit2/transports/httpclient.c @@ -1541,6 +1541,15 @@ int git_http_client_new( return 0; } +/* Update the options of an existing httpclient instance. */ +void git_http_client_set_options( + git_http_client *client, + git_http_client_options *opts) +{ + if (opts) + memcpy(&client->opts, opts, sizeof(git_http_client_options)); +} + GIT_INLINE(void) http_server_close(git_http_server *server) { if (server->stream) { diff --git a/src/libgit2/transports/httpclient.h b/src/libgit2/transports/httpclient.h index 6d0ef9edb..22c4dd093 100644 --- a/src/libgit2/transports/httpclient.h +++ b/src/libgit2/transports/httpclient.h @@ -88,6 +88,16 @@ extern int git_http_client_new( git_http_client **out, git_http_client_options *opts); +/** + * Update the options of an existing httpclient instance. + * + * @param client the httpclient instance to modify + * @param opts new options or NULL to keep existing options + */ +extern void git_http_client_set_options( + git_http_client *client, + git_http_client_options *opts); + /* * Sends a request to the host specified by the request URL. If the * method is POST, either the content_length or the chunked flag must diff --git a/src/libgit2/transports/local.c b/src/libgit2/transports/local.c index 6c754a034..4d86f1713 100644 --- a/src/libgit2/transports/local.c +++ b/src/libgit2/transports/local.c @@ -266,6 +266,17 @@ static int local_capabilities(unsigned int *capabilities, git_transport *transpo return 0; } +#ifdef GIT_EXPERIMENTAL_SHA256 +static int local_oid_type(git_oid_t *out, git_transport *transport) +{ + transport_local *t = (transport_local *)transport; + + *out = t->repo->oid_type; + + return 0; +} +#endif + static int local_ls(const git_remote_head ***out, size_t *size, git_transport *transport) { transport_local *t = (transport_local *)transport; @@ -732,6 +743,9 @@ int git_transport_local(git_transport **out, git_remote *owner, void *param) t->parent.connect = local_connect; t->parent.set_connect_opts = local_set_connect_opts; t->parent.capabilities = local_capabilities; +#ifdef GIT_EXPERIMENTAL_SHA256 + t->parent.oid_type = local_oid_type; +#endif t->parent.negotiate_fetch = local_negotiate_fetch; t->parent.download_pack = local_download_pack; t->parent.push = local_push; diff --git a/src/libgit2/transports/smart.c b/src/libgit2/transports/smart.c index 7f57dba2a..c3a764bd3 100644 --- a/src/libgit2/transports/smart.c +++ b/src/libgit2/transports/smart.c @@ -54,6 +54,12 @@ GIT_INLINE(int) git_smart__reset_stream(transport_smart *t, bool close_subtransp return -1; } + git__free(t->caps.object_format); + t->caps.object_format = NULL; + + git__free(t->caps.agent); + t->caps.agent = NULL; + return 0; } @@ -242,6 +248,30 @@ static int git_smart__capabilities(unsigned int *capabilities, git_transport *tr return 0; } +#ifdef GIT_EXPERIMENTAL_SHA256 +static int git_smart__oid_type(git_oid_t *out, git_transport *transport) +{ + transport_smart *t = GIT_CONTAINER_OF(transport, transport_smart, parent); + + *out = 0; + + if (t->caps.object_format == NULL) { + *out = GIT_OID_DEFAULT; + } else { + *out = git_oid_type_fromstr(t->caps.object_format); + + if (!*out) { + git_error_set(GIT_ERROR_INVALID, + "unknown object format '%s'", + t->caps.object_format); + return -1; + } + } + + return 0; +} +#endif + static int git_smart__ls(const git_remote_head ***out, size_t *size, git_transport *transport) { transport_smart *t = GIT_CONTAINER_OF(transport, transport_smart, parent); @@ -386,6 +416,8 @@ static void git_smart__free(git_transport *transport) git_remote_connect_options_dispose(&t->connect_opts); + git__free(t->caps.object_format); + git__free(t->caps.agent); git__free(t); } @@ -452,6 +484,9 @@ int git_transport_smart(git_transport **out, git_remote *owner, void *param) t->parent.connect = git_smart__connect; t->parent.set_connect_opts = git_smart__set_connect_opts; t->parent.capabilities = git_smart__capabilities; +#ifdef GIT_EXPERIMENTAL_SHA256 + t->parent.oid_type = git_smart__oid_type; +#endif t->parent.close = git_smart__close; t->parent.free = git_smart__free; t->parent.negotiate_fetch = git_smart__negotiate_fetch; diff --git a/src/libgit2/transports/smart.h b/src/libgit2/transports/smart.h index 9323d6c44..d71160d8e 100644 --- a/src/libgit2/transports/smart.h +++ b/src/libgit2/transports/smart.h @@ -32,6 +32,8 @@ #define GIT_CAP_SYMREF "symref" #define GIT_CAP_WANT_TIP_SHA1 "allow-tip-sha1-in-want" #define GIT_CAP_WANT_REACHABLE_SHA1 "allow-reachable-sha1-in-want" +#define GIT_CAP_OBJECT_FORMAT "object-format=" +#define GIT_CAP_AGENT "agent=" extern bool git_smart__ofs_delta_enabled; @@ -133,6 +135,8 @@ typedef struct transport_smart_caps { thin_pack:1, want_tip_sha1:1, want_reachable_sha1:1; + char *object_format; + char *agent; } transport_smart_caps; typedef int (*packetsize_cb)(size_t received, void *payload); @@ -182,7 +186,12 @@ int git_smart__get_push_stream(transport_smart *t, git_smart_subtransport_stream int git_smart__update_heads(transport_smart *t, git_vector *symrefs); /* smart_pkt.c */ -int git_pkt_parse_line(git_pkt **head, const char **endptr, const char *line, size_t linelen); +typedef struct { + git_oid_t oid_type; + int seen_capabilities: 1; +} git_pkt_parse_data; + +int git_pkt_parse_line(git_pkt **head, const char **endptr, const char *line, size_t linelen, git_pkt_parse_data *data); int git_pkt_buffer_flush(git_str *buf); int git_pkt_send_flush(GIT_SOCKET s); int git_pkt_buffer_done(git_str *buf); diff --git a/src/libgit2/transports/smart_pkt.c b/src/libgit2/transports/smart_pkt.c index b42edd0d6..5fce42175 100644 --- a/src/libgit2/transports/smart_pkt.c +++ b/src/libgit2/transports/smart_pkt.c @@ -12,6 +12,7 @@ #include "netops.h" #include "posix.h" #include "str.h" +#include "oid.h" #include "git2/types.h" #include "git2/errors.h" @@ -20,11 +21,14 @@ #include -#define PKT_LEN_SIZE 4 -static const char pkt_done_str[] = "0009done\n"; -static const char pkt_flush_str[] = "0000"; -static const char pkt_have_prefix[] = "0032have "; -static const char pkt_want_prefix[] = "0032want "; +#define PKT_DONE_STR "0009done\n" +#define PKT_FLUSH_STR "0000" +#define PKT_HAVE_PREFIX "have " +#define PKT_WANT_PREFIX "want " + +#define PKT_LEN_SIZE 4 +#define PKT_MAX_SIZE 0xffff +#define PKT_MAX_WANTLEN (PKT_LEN_SIZE + CONST_STRLEN(PKT_WANT_PREFIX) + GIT_OID_MAX_HEXSIZE + 1) static int flush_pkt(git_pkt **out) { @@ -53,10 +57,11 @@ static int ack_pkt(git_pkt **out, const char *line, size_t len) line += 4; len -= 4; - if (len < GIT_OID_HEXSZ || git_oid_fromstr(&pkt->oid, line) < 0) + if (len < GIT_OID_SHA1_HEXSIZE || + git_oid__fromstr(&pkt->oid, line, GIT_OID_SHA1) < 0) goto out_err; - line += GIT_OID_HEXSZ; - len -= GIT_OID_HEXSZ; + line += GIT_OID_SHA1_HEXSIZE; + len -= GIT_OID_SHA1_HEXSIZE; if (len && line[0] == ' ') { line++; @@ -210,25 +215,87 @@ static int sideband_error_pkt(git_pkt **out, const char *line, size_t len) return 0; } +static int set_data( + git_pkt_parse_data *data, + const char *line, + size_t len) +{ + const char *caps, *format_str = NULL, *eos; + size_t format_len; + git_oid_t remote_oid_type; + + GIT_ASSERT_ARG(data); + + if ((caps = memchr(line, '\0', len)) != NULL) { + caps++; + + if (strncmp(caps, "object-format=", CONST_STRLEN("object-format=")) == 0) + format_str = caps + CONST_STRLEN("object-format="); + else if ((format_str = strstr(caps, " object-format=")) != NULL) + format_str += CONST_STRLEN(" object-format="); + } + + if (format_str) { + if ((eos = strchr(format_str, ' ')) == NULL) + eos = strchr(format_str, '\0'); + + GIT_ASSERT(eos); + + format_len = eos - format_str; + + if ((remote_oid_type = git_oid_type_fromstrn(format_str, format_len)) == 0) { + git_error_set(GIT_ERROR_INVALID, "unknown remote object format '%.*s'", (int)format_len, format_str); + return -1; + } + } else { + remote_oid_type = GIT_OID_SHA1; + } + + if (!data->oid_type) { + data->oid_type = remote_oid_type; + } else if (data->oid_type != remote_oid_type) { + git_error_set(GIT_ERROR_INVALID, + "the local object format '%s' does not match the remote object format '%s'", + git_oid_type_name(data->oid_type), + git_oid_type_name(remote_oid_type)); + return -1; + } + + return 0; +} + /* * Parse an other-ref line. */ -static int ref_pkt(git_pkt **out, const char *line, size_t len) +static int ref_pkt( + git_pkt **out, + const char *line, + size_t len, + git_pkt_parse_data *data) { git_pkt_ref *pkt; - size_t alloclen; + size_t alloclen, oid_hexsize; pkt = git__calloc(1, sizeof(git_pkt_ref)); GIT_ERROR_CHECK_ALLOC(pkt); pkt->type = GIT_PKT_REF; - if (len < GIT_OID_HEXSZ || git_oid_fromstr(&pkt->head.oid, line) < 0) + /* Determine OID type from capabilities */ + if (!data->seen_capabilities && set_data(data, line, len) < 0) + return -1; + + GIT_ASSERT(data->oid_type); + oid_hexsize = git_oid_hexsize(data->oid_type); + + if (len < oid_hexsize || + git_oid__fromstr(&pkt->head.oid, line, data->oid_type) < 0) goto out_err; - line += GIT_OID_HEXSZ; - len -= GIT_OID_HEXSZ; + line += oid_hexsize; + len -= oid_hexsize; if (git__prefixncmp(line, len, " ")) goto out_err; + line++; len--; @@ -245,8 +312,14 @@ static int ref_pkt(git_pkt **out, const char *line, size_t len) memcpy(pkt->head.name, line, len); pkt->head.name[len] = '\0'; - if (strlen(pkt->head.name) < len) - pkt->capabilities = strchr(pkt->head.name, '\0') + 1; + if (strlen(pkt->head.name) < len) { + if (!data->seen_capabilities) + pkt->capabilities = strchr(pkt->head.name, '\0') + 1; + else + goto out_err; + } + + data->seen_capabilities = 1; *out = (git_pkt *)pkt; return 0; @@ -415,7 +488,11 @@ static int parse_len(size_t *out, const char *line, size_t linelen) */ int git_pkt_parse_line( - git_pkt **pkt, const char **endptr, const char *line, size_t linelen) + git_pkt **pkt, + const char **endptr, + const char *line, + size_t linelen, + git_pkt_parse_data *data) { int error; size_t len; @@ -490,7 +567,7 @@ int git_pkt_parse_line( else if (!git__prefixncmp(line, len, "unpack")) error = unpack_pkt(pkt, line, len); else - error = ref_pkt(pkt, line, len); + error = ref_pkt(pkt, line, len, data); *endptr = line + len; @@ -524,14 +601,21 @@ void git_pkt_free(git_pkt *pkt) int git_pkt_buffer_flush(git_str *buf) { - return git_str_put(buf, pkt_flush_str, strlen(pkt_flush_str)); + return git_str_put(buf, PKT_FLUSH_STR, CONST_STRLEN(PKT_FLUSH_STR)); } -static int buffer_want_with_caps(const git_remote_head *head, transport_smart_caps *caps, git_str *buf) +static int buffer_want_with_caps( + const git_remote_head *head, + transport_smart_caps *caps, + git_oid_t oid_type, + git_str *buf) { git_str str = GIT_STR_INIT; - char oid[GIT_OID_HEXSZ +1] = {0}; - size_t len; + char oid[GIT_OID_MAX_HEXSIZE]; + size_t oid_hexsize, len; + + oid_hexsize = git_oid_hexsize(oid_type); + git_oid_fmt(oid, &head->oid); /* Prefer multi_ack_detailed */ if (caps->multi_ack_detailed) @@ -557,19 +641,20 @@ static int buffer_want_with_caps(const git_remote_head *head, transport_smart_ca if (git_str_oom(&str)) return -1; - len = strlen("XXXXwant ") + GIT_OID_HEXSZ + 1 /* NUL */ + - git_str_len(&str) + 1 /* LF */; - - if (len > 0xffff) { + if (str.size > (PKT_MAX_SIZE - (PKT_MAX_WANTLEN + 1))) { git_error_set(GIT_ERROR_NET, - "tried to produce packet with invalid length %" PRIuZ, len); + "tried to produce packet with invalid caps length %" PRIuZ, str.size); return -1; } + len = PKT_LEN_SIZE + CONST_STRLEN(PKT_WANT_PREFIX) + + oid_hexsize + 1 /* NUL */ + + git_str_len(&str) + 1 /* LF */; + git_str_grow_by(buf, len); - git_oid_fmt(oid, &head->oid); git_str_printf(buf, - "%04xwant %s %s\n", (unsigned int)len, oid, git_str_cstr(&str)); + "%04x%s%.*s %s\n", (unsigned int)len, PKT_WANT_PREFIX, + (int)oid_hexsize, oid, git_str_cstr(&str)); git_str_dispose(&str); GIT_ERROR_CHECK_ALLOC_STR(buf); @@ -588,8 +673,21 @@ int git_pkt_buffer_wants( transport_smart_caps *caps, git_str *buf) { - size_t i = 0; const git_remote_head *head; + char oid[GIT_OID_MAX_HEXSIZE]; + git_oid_t oid_type; + size_t oid_hexsize, want_len, i = 0; + +#ifdef GIT_EXPERIMENTAL_SHA256 + oid_type = count > 0 ? refs[0]->oid.type : GIT_OID_SHA1; +#else + oid_type = GIT_OID_SHA1; +#endif + + oid_hexsize = git_oid_hexsize(oid_type); + + want_len = PKT_LEN_SIZE + CONST_STRLEN(PKT_WANT_PREFIX) + + oid_hexsize + 1 /* LF */; if (caps->common) { for (; i < count; ++i) { @@ -598,23 +696,24 @@ int git_pkt_buffer_wants( break; } - if (buffer_want_with_caps(refs[i], caps, buf) < 0) + if (buffer_want_with_caps(refs[i], caps, oid_type, buf) < 0) return -1; i++; } for (; i < count; ++i) { - char oid[GIT_OID_HEXSZ]; - head = refs[i]; + if (head->local) continue; git_oid_fmt(oid, &head->oid); - git_str_put(buf, pkt_want_prefix, strlen(pkt_want_prefix)); - git_str_put(buf, oid, GIT_OID_HEXSZ); - git_str_putc(buf, '\n'); + + git_str_printf(buf, "%04x%s%.*s\n", + (unsigned int)want_len, PKT_WANT_PREFIX, + (int)oid_hexsize, oid); + if (git_str_oom(buf)) return -1; } @@ -624,14 +723,27 @@ int git_pkt_buffer_wants( int git_pkt_buffer_have(git_oid *oid, git_str *buf) { - char oidhex[GIT_OID_HEXSZ + 1]; + char oid_str[GIT_OID_MAX_HEXSIZE]; + git_oid_t oid_type; + size_t oid_hexsize, have_len; - memset(oidhex, 0x0, sizeof(oidhex)); - git_oid_fmt(oidhex, oid); - return git_str_printf(buf, "%s%s\n", pkt_have_prefix, oidhex); +#ifdef GIT_EXPERIMENTAL_SHA256 + oid_type = oid->type; +#else + oid_type = GIT_OID_SHA1; +#endif + + oid_hexsize = git_oid_hexsize(oid_type); + have_len = PKT_LEN_SIZE + CONST_STRLEN(PKT_HAVE_PREFIX) + + oid_hexsize + 1 /* LF */; + + git_oid_fmt(oid_str, oid); + return git_str_printf(buf, "%04x%s%.*s\n", + (unsigned int)have_len, PKT_HAVE_PREFIX, + (int)oid_hexsize, oid_str); } int git_pkt_buffer_done(git_str *buf) { - return git_str_puts(buf, pkt_done_str); + return git_str_put(buf, PKT_DONE_STR, CONST_STRLEN(PKT_DONE_STR)); } diff --git a/src/libgit2/transports/smart_protocol.c b/src/libgit2/transports/smart_protocol.c index 8cf027133..0d47acafe 100644 --- a/src/libgit2/transports/smart_protocol.c +++ b/src/libgit2/transports/smart_protocol.c @@ -32,6 +32,7 @@ int git_smart__store_refs(transport_smart *t, int flushes) int error, flush = 0, recvd; const char *line_end = NULL; git_pkt *pkt = NULL; + git_pkt_parse_data pkt_parse_data = { 0 }; size_t i; /* Clear existing refs in case git_remote_connect() is called again @@ -45,7 +46,7 @@ int git_smart__store_refs(transport_smart *t, int flushes) do { if (buf->offset > 0) - error = git_pkt_parse_line(&pkt, &line_end, buf->data, buf->offset); + error = git_pkt_parse_line(&pkt, &line_end, buf->data, buf->offset, &pkt_parse_data); else error = GIT_EBUFS; @@ -133,9 +134,12 @@ on_invalid: return -1; } -int git_smart__detect_caps(git_pkt_ref *pkt, transport_smart_caps *caps, git_vector *symrefs) +int git_smart__detect_caps( + git_pkt_ref *pkt, + transport_smart_caps *caps, + git_vector *symrefs) { - const char *ptr; + const char *ptr, *start; /* No refs or capabilities, odd but not a problem */ if (pkt == NULL || pkt->capabilities == NULL) @@ -207,13 +211,35 @@ int git_smart__detect_caps(git_pkt_ref *pkt, transport_smart_caps *caps, git_vec if (!git__prefixcmp(ptr, GIT_CAP_WANT_TIP_SHA1)) { caps->common = caps->want_tip_sha1 = 1; - ptr += strlen(GIT_CAP_DELETE_REFS); + ptr += strlen(GIT_CAP_WANT_TIP_SHA1); continue; } if (!git__prefixcmp(ptr, GIT_CAP_WANT_REACHABLE_SHA1)) { caps->common = caps->want_reachable_sha1 = 1; - ptr += strlen(GIT_CAP_DELETE_REFS); + ptr += strlen(GIT_CAP_WANT_REACHABLE_SHA1); + continue; + } + + if (!git__prefixcmp(ptr, GIT_CAP_OBJECT_FORMAT)) { + ptr += strlen(GIT_CAP_OBJECT_FORMAT); + + start = ptr; + ptr = strchr(ptr, ' '); + + if ((caps->object_format = git__strndup(start, (ptr - start))) == NULL) + return -1; + continue; + } + + if (!git__prefixcmp(ptr, GIT_CAP_AGENT)) { + ptr += strlen(GIT_CAP_AGENT); + + start = ptr; + ptr = strchr(ptr, ' '); + + if ((caps->agent = git__strndup(start, (ptr - start))) == NULL) + return -1; continue; } @@ -228,11 +254,12 @@ static int recv_pkt(git_pkt **out_pkt, git_pkt_type *out_type, gitno_buffer *buf { const char *ptr = buf->data, *line_end = ptr; git_pkt *pkt = NULL; + git_pkt_parse_data pkt_parse_data = { 0 }; int error = 0, ret; do { if (buf->offset > 0) - error = git_pkt_parse_line(&pkt, &line_end, ptr, buf->offset); + error = git_pkt_parse_line(&pkt, &line_end, ptr, buf->offset, &pkt_parse_data); else error = GIT_EBUFS; @@ -643,12 +670,12 @@ static int gen_pktline(git_str *buf, git_push *push) { push_spec *spec; size_t i, len; - char old_id[GIT_OID_HEXSZ+1], new_id[GIT_OID_HEXSZ+1]; + char old_id[GIT_OID_SHA1_HEXSIZE+1], new_id[GIT_OID_SHA1_HEXSIZE+1]; - old_id[GIT_OID_HEXSZ] = '\0'; new_id[GIT_OID_HEXSZ] = '\0'; + old_id[GIT_OID_SHA1_HEXSIZE] = '\0'; new_id[GIT_OID_SHA1_HEXSIZE] = '\0'; git_vector_foreach(&push->specs, i, spec) { - len = 2*GIT_OID_HEXSZ + 7 + strlen(spec->refspec.dst); + len = 2*GIT_OID_SHA1_HEXSIZE + 7 + strlen(spec->refspec.dst); if (i == 0) { ++len; /* '\0' */ @@ -723,6 +750,7 @@ static int add_push_report_pkt(git_push *push, git_pkt *pkt) static int add_push_report_sideband_pkt(git_push *push, git_pkt_data *data_pkt, git_str *data_pkt_buf) { git_pkt *pkt; + git_pkt_parse_data pkt_parse_data = { 0 }; const char *line, *line_end = NULL; size_t line_len; int error; @@ -741,7 +769,7 @@ static int add_push_report_sideband_pkt(git_push *push, git_pkt_data *data_pkt, } while (line_len > 0) { - error = git_pkt_parse_line(&pkt, &line_end, line, line_len); + error = git_pkt_parse_line(&pkt, &line_end, line, line_len, &pkt_parse_data); if (error == GIT_EBUFS) { /* Buffer the data when the inner packet is split @@ -777,6 +805,7 @@ done: static int parse_report(transport_smart *transport, git_push *push) { git_pkt *pkt = NULL; + git_pkt_parse_data pkt_parse_data = { 0 }; const char *line_end = NULL; gitno_buffer *buf = &transport->buffer; int error, recvd; @@ -785,7 +814,8 @@ static int parse_report(transport_smart *transport, git_push *push) for (;;) { if (buf->offset > 0) error = git_pkt_parse_line(&pkt, &line_end, - buf->data, buf->offset); + buf->data, buf->offset, + &pkt_parse_data); else error = GIT_EBUFS; @@ -1020,7 +1050,7 @@ int git_smart__push(git_transport *transport, git_push *push) #ifdef PUSH_DEBUG { git_remote_head *head; - char hex[GIT_OID_HEXSZ+1]; hex[GIT_OID_HEXSZ] = '\0'; + char hex[GIT_OID_SHA1_HEXSIZE+1]; hex[GIT_OID_SHA1_HEXSIZE] = '\0'; git_vector_foreach(&push->remote->refs, i, head) { git_oid_fmt(hex, &head->oid); diff --git a/src/libgit2/transports/ssh.c b/src/libgit2/transports/ssh.c index 85e779744..5500ea100 100644 --- a/src/libgit2/transports/ssh.c +++ b/src/libgit2/transports/ssh.c @@ -16,6 +16,7 @@ #include "netops.h" #include "smart.h" #include "streams/socket.h" +#include "sysdir.h" #include "git2/credential.h" #include "git2/sys/credential.h" @@ -245,8 +246,10 @@ static int ssh_agent_auth(LIBSSH2_SESSION *session, git_credential_ssh_key *c) { rc = libssh2_agent_connect(agent); - if (rc != LIBSSH2_ERROR_NONE) + if (rc != LIBSSH2_ERROR_NONE) { + rc = LIBSSH2_ERROR_AUTHENTICATION_FAILED; goto shutdown; + } rc = libssh2_agent_list_identities(agent); @@ -421,7 +424,8 @@ static int request_creds(git_credential **out, ssh_subtransport *t, const char * return 0; } -#define KNOWN_HOSTS_FILE ".ssh/known_hosts" +#define SSH_DIR ".ssh" +#define KNOWN_HOSTS_FILE "known_hosts" /* * Load the known_hosts file. @@ -430,16 +434,14 @@ static int request_creds(git_credential **out, ssh_subtransport *t, const char * */ static int load_known_hosts(LIBSSH2_KNOWNHOSTS **hosts, LIBSSH2_SESSION *session) { - git_str path = GIT_STR_INIT, home = GIT_STR_INIT; + git_str path = GIT_STR_INIT, sshdir = GIT_STR_INIT; LIBSSH2_KNOWNHOSTS *known_hosts = NULL; int error; GIT_ASSERT_ARG(hosts); - if ((error = git__getenv(&home, "HOME")) < 0) - return error; - - if ((error = git_str_joinpath(&path, git_str_cstr(&home), KNOWN_HOSTS_FILE)) < 0) + if ((error = git_sysdir_expand_homedir_file(&sshdir, SSH_DIR)) < 0 || + (error = git_str_joinpath(&path, git_str_cstr(&sshdir), KNOWN_HOSTS_FILE)) < 0) goto out; if ((known_hosts = libssh2_knownhost_init(session)) == NULL) { @@ -461,34 +463,32 @@ static int load_known_hosts(LIBSSH2_KNOWNHOSTS **hosts, LIBSSH2_SESSION *session out: *hosts = known_hosts; - git_str_clear(&home); - git_str_clear(&path); + git_str_dispose(&sshdir); + git_str_dispose(&path); return error; } -static const char *hostkey_type_to_string(int type) +static void add_hostkey_pref_if_avail( + LIBSSH2_KNOWNHOSTS *known_hosts, + const char *hostname, + int port, + git_str *prefs, + int type, + const char *type_name) { - switch (type) { - case LIBSSH2_KNOWNHOST_KEY_SSHRSA: - return "ssh-rsa"; - case LIBSSH2_KNOWNHOST_KEY_SSHDSS: - return "ssh-dss"; -#ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_256 - case LIBSSH2_KNOWNHOST_KEY_ECDSA_256: - return "ecdsa-sha2-nistp256"; - case LIBSSH2_KNOWNHOST_KEY_ECDSA_384: - return "ecdsa-sha2-nistp384"; - case LIBSSH2_KNOWNHOST_KEY_ECDSA_521: - return "ecdsa-sha2-nistp521"; -#endif -#ifdef LIBSSH2_KNOWNHOST_KEY_ED25519 - case LIBSSH2_KNOWNHOST_KEY_ED25519: - return "ssh-ed25519"; -#endif - } + struct libssh2_knownhost *host = NULL; + const char key = '\0'; + int mask = LIBSSH2_KNOWNHOST_TYPE_PLAIN | LIBSSH2_KNOWNHOST_KEYENC_RAW | type; + int error; - return NULL; + error = libssh2_knownhost_checkp(known_hosts, hostname, port, &key, 1, mask, &host); + if (error == LIBSSH2_KNOWNHOST_CHECK_MISMATCH) { + if (git_str_len(prefs) > 0) { + git_str_putc(prefs, ','); + } + git_str_puts(prefs, type_name); + } } /* @@ -496,27 +496,27 @@ static const char *hostkey_type_to_string(int type) * look it up with a nonsense key and using that mismatch to figure out what key * we do have stored for the host. * - * Returns the string to pass to libssh2_session_method_pref or NULL if we were - * unable to find anything or an error happened. + * Populates prefs with the string to pass to libssh2_session_method_pref. */ -static const char *find_hostkey_preference(LIBSSH2_KNOWNHOSTS *known_hosts, const char *hostname, int port) +static void find_hostkey_preference( + LIBSSH2_KNOWNHOSTS *known_hosts, + const char *hostname, + int port, + git_str *prefs) { - struct libssh2_knownhost *host = NULL; - /* Specify no key type so we don't filter on that */ - int type = LIBSSH2_KNOWNHOST_TYPE_PLAIN | LIBSSH2_KNOWNHOST_KEYENC_RAW; - const char key = '\0'; - int error; - /* - * In case of mismatch, we can find the type of key from known_hosts in - * the returned host's information as it means that an entry was found - * but our nonsense key obviously didn't match. + * The order here is important as it indicates the priority of what will + * be preferred. */ - error = libssh2_knownhost_checkp(known_hosts, hostname, port, &key, 1, type, &host); - if (error == LIBSSH2_KNOWNHOST_CHECK_MISMATCH) - return hostkey_type_to_string(host->typemask & LIBSSH2_KNOWNHOST_KEY_MASK); - - return NULL; +#ifdef LIBSSH2_KNOWNHOST_KEY_ED25519 + add_hostkey_pref_if_avail(known_hosts, hostname, port, prefs, LIBSSH2_KNOWNHOST_KEY_ED25519, "ssh-ed25519"); +#endif +#ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_256 + add_hostkey_pref_if_avail(known_hosts, hostname, port, prefs, LIBSSH2_KNOWNHOST_KEY_ECDSA_256, "ecdsa-sha2-nistp256"); + add_hostkey_pref_if_avail(known_hosts, hostname, port, prefs, LIBSSH2_KNOWNHOST_KEY_ECDSA_384, "ecdsa-sha2-nistp384"); + add_hostkey_pref_if_avail(known_hosts, hostname, port, prefs, LIBSSH2_KNOWNHOST_KEY_ECDSA_521, "ecdsa-sha2-nistp521"); +#endif + add_hostkey_pref_if_avail(known_hosts, hostname, port, prefs, LIBSSH2_KNOWNHOST_KEY_SSHRSA, "ssh-rsa"); } static int _git_ssh_session_create( @@ -526,11 +526,11 @@ static int _git_ssh_session_create( int port, git_stream *io) { - int rc = 0; + git_socket_stream *socket = GIT_CONTAINER_OF(io, git_socket_stream, parent); LIBSSH2_SESSION *s; LIBSSH2_KNOWNHOSTS *known_hosts; - git_socket_stream *socket = GIT_CONTAINER_OF(io, git_socket_stream, parent); - const char *keytype = NULL; + git_str prefs = GIT_STR_INIT; + int rc = 0; GIT_ASSERT_ARG(session); GIT_ASSERT_ARG(hosts); @@ -547,16 +547,17 @@ static int _git_ssh_session_create( return -1; } - if ((keytype = find_hostkey_preference(known_hosts, hostname, port)) != NULL) { + find_hostkey_preference(known_hosts, hostname, port, &prefs); + if (git_str_len(&prefs) > 0) { do { - rc = libssh2_session_method_pref(s, LIBSSH2_METHOD_HOSTKEY, keytype); + rc = libssh2_session_method_pref(s, LIBSSH2_METHOD_HOSTKEY, git_str_cstr(&prefs)); } while (LIBSSH2_ERROR_EAGAIN == rc || LIBSSH2_ERROR_TIMEOUT == rc); if (rc != LIBSSH2_ERROR_NONE) { ssh_error(s, "failed to set hostkey preference"); goto on_error; } } - + git_str_dispose(&prefs); do { rc = libssh2_session_handshake(s, socket->s); @@ -753,7 +754,7 @@ static int check_certificate( if (error == GIT_PASSTHROUGH) { error = git_error_state_restore(&previous_error); } else if (error < 0 && !git_error_last()) { - git_error_set(GIT_ERROR_NET, "user canceled hostkey check"); + git_error_set(GIT_ERROR_NET, "unknown remote host key"); } git_error_state_free(&previous_error); @@ -787,15 +788,8 @@ static int _git_ssh_setup_conn( s->session = NULL; s->channel = NULL; - if (git_net_str_is_url(url)) - error = git_net_url_parse(&s->url, url); - else - error = git_net_url_parse_scp(&s->url, url); - - if (error < 0) - goto done; - - if ((error = git_socket_stream_new(&s->io, s->url.host, s->url.port)) < 0 || + if ((error = git_net_url_parse_standard_or_scp(&s->url, url)) < 0 || + (error = git_socket_stream_new(&s->io, s->url.host, s->url.port)) < 0 || (error = git_stream_connect(s->io)) < 0) goto done; @@ -805,8 +799,11 @@ static int _git_ssh_setup_conn( * as part of the stream connection, but that's not something that's * exposed. */ - if (git__strntol32(&port, s->url.port, strlen(s->url.port), NULL, 10) < 0) - port = -1; + if (git__strntol32(&port, s->url.port, strlen(s->url.port), NULL, 10) < 0) { + git_error_set(GIT_ERROR_NET, "invalid port to ssh: %s", s->url.port); + error = -1; + goto done; + } if ((error = _git_ssh_session_create(&session, &known_hosts, s->url.host, port, s->io)) < 0) goto done; @@ -1009,7 +1006,7 @@ static int list_auth_methods(int *out, LIBSSH2_SESSION *session, const char *use /* either error, or the remote accepts NONE auth, which is bizarre, let's punt */ if (list == NULL && !libssh2_userauth_authenticated(session)) { - ssh_error(session, "Failed to retrieve list of SSH authentication methods"); + ssh_error(session, "remote rejected authentication"); return GIT_EAUTH; } diff --git a/src/libgit2/transports/winhttp.c b/src/libgit2/transports/winhttp.c index 8ec5b37c5..098227607 100644 --- a/src/libgit2/transports/winhttp.c +++ b/src/libgit2/transports/winhttp.c @@ -562,18 +562,23 @@ static int winhttp_stream_connect(winhttp_stream *s) for (i = 0; i < t->owner->connect_opts.custom_headers.count; i++) { if (t->owner->connect_opts.custom_headers.strings[i]) { + wchar_t *custom_header_wide = NULL; + git_str_clear(&buf); git_str_puts(&buf, t->owner->connect_opts.custom_headers.strings[i]); - if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_str_cstr(&buf)) < 0) { - git_error_set(GIT_ERROR_OS, "failed to convert custom header to wide characters"); + + /* Convert header to wide characters */ + if ((error = git__utf8_to_16_alloc(&custom_header_wide, git_str_cstr(&buf))) < 0) + goto on_error; + + if (!WinHttpAddRequestHeaders(s->request, custom_header_wide, (ULONG)-1L, + WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE)) { + git_error_set(GIT_ERROR_OS, "failed to add a header to the request"); + git__free(custom_header_wide); goto on_error; } - if (!WinHttpAddRequestHeaders(s->request, ct, (ULONG)-1L, - WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE)) { - git_error_set(GIT_ERROR_OS, "failed to add a header to the request"); - goto on_error; - } + git__free(custom_header_wide); } } diff --git a/src/libgit2/tree-cache.c b/src/libgit2/tree-cache.c index cd69e7bf8..19fad85ae 100644 --- a/src/libgit2/tree-cache.c +++ b/src/libgit2/tree-cache.c @@ -111,11 +111,11 @@ static int read_tree_internal(git_tree_cache **out, /* The SHA1 is only there if it's not invalidated */ if (tree->entry_count >= 0) { /* 160-bit SHA-1 for this tree and it's children */ - if (buffer + GIT_OID_RAWSZ > buffer_end) + if (buffer + GIT_OID_SHA1_SIZE > buffer_end) goto corrupted; - git_oid_fromraw(&tree->oid, (const unsigned char *)buffer); - buffer += GIT_OID_RAWSZ; + git_oid__fromraw(&tree->oid, (const unsigned char *)buffer, GIT_OID_SHA1); + buffer += GIT_OID_SHA1_SIZE; } /* Parse children: */ @@ -263,7 +263,7 @@ static void write_tree(git_str *out, git_tree_cache *tree) git_str_printf(out, "%s%c%"PRIdZ" %"PRIuZ"\n", tree->name, 0, tree->entry_count, tree->children_count); if (tree->entry_count != -1) - git_str_put(out, (char *)&tree->oid.id, GIT_OID_RAWSZ); + git_str_put(out, (char *)&tree->oid.id, GIT_OID_SHA1_SIZE); for (i = 0; i < tree->children_count; i++) write_tree(out, tree->children[i]); diff --git a/src/libgit2/tree.c b/src/libgit2/tree.c index a5371fd87..9293d9422 100644 --- a/src/libgit2/tree.c +++ b/src/libgit2/tree.c @@ -85,11 +85,17 @@ static git_tree_entry *alloc_entry(const char *filename, size_t filename_len, co char *filename_ptr; size_t tree_len; +#ifdef GIT_EXPERIMENTAL_SHA256 + size_t oid_size = git_oid_size(id->type); +#else + size_t oid_size = GIT_OID_SHA1_SIZE; +#endif + TREE_ENTRY_CHECK_NAMELEN(filename_len); if (GIT_ADD_SIZET_OVERFLOW(&tree_len, sizeof(git_tree_entry), filename_len) || GIT_ADD_SIZET_OVERFLOW(&tree_len, tree_len, 1) || - GIT_ADD_SIZET_OVERFLOW(&tree_len, tree_len, GIT_OID_RAWSZ)) + GIT_ADD_SIZET_OVERFLOW(&tree_len, tree_len, oid_size)) return NULL; entry = git__calloc(1, tree_len); @@ -383,11 +389,12 @@ static int parse_mode(uint16_t *mode_out, const char *buffer, size_t buffer_len, return 0; } -int git_tree__parse_raw(void *_tree, const char *data, size_t size) +int git_tree__parse_raw(void *_tree, const char *data, size_t size, git_oid_t oid_type) { git_tree *tree = _tree; const char *buffer; const char *buffer_end; + const long oid_size = (long)git_oid_size(oid_type); buffer = data; buffer_end = buffer + size; @@ -414,35 +421,33 @@ int git_tree__parse_raw(void *_tree, const char *data, size_t size) if ((filename_len = nul - buffer) == 0 || filename_len > UINT16_MAX) return tree_parse_error("failed to parse tree: can't parse filename", NULL); - if ((buffer_end - (nul + 1)) < GIT_OID_RAWSZ) + if ((buffer_end - (nul + 1)) < (long)oid_size) return tree_parse_error("failed to parse tree: can't parse OID", NULL); /* Allocate the entry */ - { - entry = git_array_alloc(tree->entries); - GIT_ERROR_CHECK_ALLOC(entry); - - entry->attr = attr; - entry->filename_len = (uint16_t)filename_len; - entry->filename = buffer; - git_oid_fromraw(&entry->oid, ((unsigned char *) buffer + filename_len + 1)); - } + entry = git_array_alloc(tree->entries); + GIT_ERROR_CHECK_ALLOC(entry); + entry->attr = attr; + entry->filename_len = (uint16_t)filename_len; + entry->filename = buffer; buffer += filename_len + 1; - buffer += GIT_OID_RAWSZ; + + git_oid__fromraw(&entry->oid, (unsigned char *)buffer, oid_type); + buffer += oid_size; } return 0; } -int git_tree__parse(void *_tree, git_odb_object *odb_obj) +int git_tree__parse(void *_tree, git_odb_object *odb_obj, git_oid_t oid_type) { git_tree *tree = _tree; const char *data = git_odb_object_data(odb_obj); size_t size = git_odb_object_size(odb_obj); int error; - if ((error = git_tree__parse_raw(tree, data, size)) < 0 || + if ((error = git_tree__parse_raw(tree, data, size, oid_type)) < 0 || (error = git_odb_object_dup(&tree->odb_obj, odb_obj)) < 0) return error; @@ -506,6 +511,7 @@ static int git_treebuilder__write_with_buffer( git_odb *odb; git_tree_entry *entry; git_vector entries = GIT_VECTOR_INIT; + size_t oid_size = git_oid_size(bld->repo->oid_type); git_str_clear(buf); @@ -529,7 +535,7 @@ static int git_treebuilder__write_with_buffer( git_str_printf(buf, "%o ", entry->attr); git_str_put(buf, entry->filename, entry->filename_len + 1); - git_str_put(buf, (char *)entry->oid.id, GIT_OID_RAWSZ); + git_str_put(buf, (char *)entry->oid.id, oid_size); if (git_str_oom(buf)) { error = -1; diff --git a/src/libgit2/tree.h b/src/libgit2/tree.h index 0dd963ff2..5088450ab 100644 --- a/src/libgit2/tree.h +++ b/src/libgit2/tree.h @@ -41,8 +41,8 @@ GIT_INLINE(bool) git_tree_entry__is_tree(const struct git_tree_entry *e) } void git_tree__free(void *tree); -int git_tree__parse(void *tree, git_odb_object *obj); -int git_tree__parse_raw(void *_tree, const char *data, size_t size); +int git_tree__parse(void *tree, git_odb_object *obj, git_oid_t oid_type); +int git_tree__parse_raw(void *_tree, const char *data, size_t size, git_oid_t oid_type); /** * Write a tree to the given repository diff --git a/src/libgit2/worktree.c b/src/libgit2/worktree.c index 2ac2274f1..82e1d2d7e 100644 --- a/src/libgit2/worktree.c +++ b/src/libgit2/worktree.c @@ -187,6 +187,11 @@ int git_worktree_lookup(git_worktree **out, git_repository *repo, const char *na if ((error = git_str_join3(&path, '/', repo->commondir, "worktrees", name)) < 0) goto out; + if (!git_fs_path_isdir(path.ptr)) { + error = GIT_ENOTFOUND; + goto out; + } + if ((error = (open_worktree_dir(out, git_repository_workdir(repo), path.ptr, name))) < 0) goto out; diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index b2833954d..ee35eb961 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -4,8 +4,11 @@ add_library(util OBJECT) set_target_properties(util PROPERTIES C_STANDARD 90) set_target_properties(util PROPERTIES C_EXTENSIONS OFF) +configure_file(git2_features.h.in git2_features.h) + set(UTIL_INCLUDES - "${PROJECT_BINARY_DIR}/src" + "${PROJECT_BINARY_DIR}/src/util" + "${PROJECT_BINARY_DIR}/include" "${PROJECT_SOURCE_DIR}/src/util" "${PROJECT_SOURCE_DIR}/include") @@ -34,6 +37,7 @@ if(USE_SHA1 STREQUAL "CollisionDetection") target_compile_definitions(util PRIVATE SHA1DC_CUSTOM_INCLUDE_SHA1_C=\"git2_util.h\") target_compile_definitions(util PRIVATE SHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C=\"git2_util.h\") elseif(USE_SHA1 STREQUAL "OpenSSL" OR USE_SHA1 STREQUAL "OpenSSL-Dynamic") + add_definitions(-DOPENSSL_API_COMPAT=0x10100000L) file(GLOB UTIL_SRC_SHA1 hash/openssl.*) elseif(USE_SHA1 STREQUAL "CommonCrypto") file(GLOB UTIL_SRC_SHA1 hash/common_crypto.*) @@ -50,6 +54,7 @@ list(SORT UTIL_SRC_SHA1) if(USE_SHA256 STREQUAL "Builtin") file(GLOB UTIL_SRC_SHA256 hash/builtin.* hash/rfc6234/*) elseif(USE_SHA256 STREQUAL "OpenSSL" OR USE_SHA256 STREQUAL "OpenSSL-Dynamic") + add_definitions(-DOPENSSL_API_COMPAT=0x10100000L) file(GLOB UTIL_SRC_SHA256 hash/openssl.*) elseif(USE_SHA256 STREQUAL "CommonCrypto") file(GLOB UTIL_SRC_SHA256 hash/common_crypto.*) diff --git a/src/util/fs_path.c b/src/util/fs_path.c index 6c87bfd01..b52867e77 100644 --- a/src/util/fs_path.c +++ b/src/util/fs_path.c @@ -1855,7 +1855,7 @@ static int file_owner_sid(PSID *out, const char *path) PSECURITY_DESCRIPTOR descriptor = NULL; PSID owner_sid; DWORD ret; - int error = -1; + int error = GIT_EINVALID; if (git_win32_path_from_utf8(path_w32, path) < 0) return -1; diff --git a/src/util/futils.c b/src/util/futils.c index cb872de09..084f1cd28 100644 --- a/src/util/futils.c +++ b/src/util/futils.c @@ -13,9 +13,6 @@ #include "rand.h" #include -#if GIT_WIN32 -#include "win32/findfile.h" -#endif #define GIT_FILEMODE_DEFAULT 0100666 diff --git a/src/features.h.in b/src/util/git2_features.h.in similarity index 100% rename from src/features.h.in rename to src/util/git2_features.h.in diff --git a/src/util/git2_util.h b/src/util/git2_util.h index ad3f1c71f..c62dc2419 100644 --- a/src/util/git2_util.h +++ b/src/util/git2_util.h @@ -7,8 +7,8 @@ #ifndef INCLUDE_git2_util_h__ #define INCLUDE_git2_util_h__ -#ifndef LIBGIT2_NO_FEATURES_H -# include "git2/sys/features.h" +#if !defined(LIBGIT2_NO_FEATURES_H) +# include "git2_features.h" #endif #include "git2/common.h" diff --git a/src/util/hash.h b/src/util/hash.h index 387c5a66f..21fcaf045 100644 --- a/src/util/hash.h +++ b/src/util/hash.h @@ -23,6 +23,8 @@ typedef enum { GIT_HASH_ALGORITHM_SHA256 } git_hash_algorithm_t; +#define GIT_HASH_MAX_SIZE GIT_HASH_SHA256_SIZE + typedef struct git_hash_ctx { union { git_hash_sha1_ctx sha1; @@ -45,4 +47,15 @@ int git_hash_vec(unsigned char *out, git_str_vec *vec, size_t n, git_hash_algori int git_hash_fmt(char *out, unsigned char *hash, size_t hash_len); +GIT_INLINE(size_t) git_hash_size(git_hash_algorithm_t algorithm) { + switch (algorithm) { + case GIT_HASH_ALGORITHM_SHA1: + return GIT_HASH_SHA1_SIZE; + case GIT_HASH_ALGORITHM_SHA256: + return GIT_HASH_SHA256_SIZE; + default: + return 0; + } +} + #endif diff --git a/src/util/hash/openssl.c b/src/util/hash/openssl.c index 649358ca2..eaf91e74c 100644 --- a/src/util/hash/openssl.c +++ b/src/util/hash/openssl.c @@ -10,8 +10,8 @@ #ifdef GIT_OPENSSL_DYNAMIC # include -int handle_count; -void *openssl_handle; +static int handle_count; +static void *openssl_handle; static int git_hash_openssl_global_shutdown(void) { @@ -30,7 +30,8 @@ static int git_hash_openssl_global_init(void) (openssl_handle = dlopen("libssl.1.1.dylib", RTLD_NOW)) == NULL && (openssl_handle = dlopen("libssl.so.1.0.0", RTLD_NOW)) == NULL && (openssl_handle = dlopen("libssl.1.0.0.dylib", RTLD_NOW)) == NULL && - (openssl_handle = dlopen("libssl.so.10", RTLD_NOW)) == NULL) { + (openssl_handle = dlopen("libssl.so.10", RTLD_NOW)) == NULL && + (openssl_handle = dlopen("libssl.so.3", RTLD_NOW)) == NULL) { git_error_set(GIT_ERROR_SSL, "could not load ssl libraries"); return -1; } diff --git a/src/util/hash/rfc6234/sha.h b/src/util/hash/rfc6234/sha.h index e0c400ca1..0fbcc50d3 100644 --- a/src/util/hash/rfc6234/sha.h +++ b/src/util/hash/rfc6234/sha.h @@ -191,49 +191,6 @@ typedef struct SHA256Context SHA224Context; */ typedef struct SHA512Context SHA384Context; -/* - * This structure holds context information for all SHA - * hashing operations. - */ -typedef struct USHAContext { - int whichSha; /* which SHA is being used */ - union { - SHA1Context sha1Context; - SHA224Context sha224Context; SHA256Context sha256Context; - SHA384Context sha384Context; SHA512Context sha512Context; - } ctx; -} USHAContext; - -/* - * This structure will hold context information for the HMAC - * keyed-hashing operation. - */ -typedef struct HMACContext { - int whichSha; /* which SHA is being used */ - int hashSize; /* hash size of SHA being used */ - int blockSize; /* block size of SHA being used */ - USHAContext shaContext; /* SHA context */ - unsigned char k_opad[USHA_Max_Message_Block_Size]; - /* outer padding - key XORd with opad */ - int Computed; /* Is the MAC computed? */ - int Corrupted; /* Cumulative corruption code */ - -} HMACContext; - -/* - * This structure will hold context information for the HKDF - * extract-and-expand Key Derivation Functions. - */ -typedef struct HKDFContext { - int whichSha; /* which SHA is being used */ - HMACContext hmacContext; - int hashSize; /* hash size of SHA being used */ - unsigned char prk[USHAMaxHashSize]; - /* pseudo-random key - output of hkdfInput */ - int Computed; /* Is the key material computed? */ - int Corrupted; /* Cumulative corruption code */ -} HKDFContext; - /* * Function Prototypes */ @@ -283,73 +240,4 @@ extern int SHA512FinalBits(SHA512Context *, uint8_t bits, extern int SHA512Result(SHA512Context *, uint8_t Message_Digest[SHA512HashSize]); -/* Unified SHA functions, chosen by whichSha */ -extern int USHAReset(USHAContext *context, SHAversion whichSha); -extern int USHAInput(USHAContext *context, - const uint8_t *bytes, unsigned int bytecount); -extern int USHAFinalBits(USHAContext *context, - uint8_t bits, unsigned int bit_count); -extern int USHAResult(USHAContext *context, - uint8_t Message_Digest[USHAMaxHashSize]); -extern int USHABlockSize(enum SHAversion whichSha); -extern int USHAHashSize(enum SHAversion whichSha); -extern int USHAHashSizeBits(enum SHAversion whichSha); -extern const char *USHAHashName(enum SHAversion whichSha); - -/* - * HMAC Keyed-Hashing for Message Authentication, RFC 2104, - * for all SHAs. - * This interface allows a fixed-length text input to be used. - */ -extern int hmac(SHAversion whichSha, /* which SHA algorithm to use */ - const unsigned char *text, /* pointer to data stream */ - int text_len, /* length of data stream */ - const unsigned char *key, /* pointer to authentication key */ - int key_len, /* length of authentication key */ - uint8_t digest[USHAMaxHashSize]); /* caller digest to fill in */ - -/* - * HMAC Keyed-Hashing for Message Authentication, RFC 2104, - * for all SHAs. - * This interface allows any length of text input to be used. - */ -extern int hmacReset(HMACContext *context, enum SHAversion whichSha, - const unsigned char *key, int key_len); -extern int hmacInput(HMACContext *context, const unsigned char *text, - int text_len); -extern int hmacFinalBits(HMACContext *context, uint8_t bits, - unsigned int bit_count); -extern int hmacResult(HMACContext *context, - uint8_t digest[USHAMaxHashSize]); - -/* - * HKDF HMAC-based Extract-and-Expand Key Derivation Function, - * RFC 5869, for all SHAs. - */ -extern int hkdf(SHAversion whichSha, const unsigned char *salt, - int salt_len, const unsigned char *ikm, int ikm_len, - const unsigned char *info, int info_len, - uint8_t okm[ ], int okm_len); -extern int hkdfExtract(SHAversion whichSha, const unsigned char *salt, - int salt_len, const unsigned char *ikm, - int ikm_len, uint8_t prk[USHAMaxHashSize]); -extern int hkdfExpand(SHAversion whichSha, const uint8_t prk[ ], - int prk_len, const unsigned char *info, - int info_len, uint8_t okm[ ], int okm_len); - -/* - * HKDF HMAC-based Extract-and-Expand Key Derivation Function, - * RFC 5869, for all SHAs. - * This interface allows any length of text input to be used. - */ -extern int hkdfReset(HKDFContext *context, enum SHAversion whichSha, - const unsigned char *salt, int salt_len); -extern int hkdfInput(HKDFContext *context, const unsigned char *ikm, - int ikm_len); -extern int hkdfFinalBits(HKDFContext *context, uint8_t ikm_bits, - unsigned int ikm_bit_count); -extern int hkdfResult(HKDFContext *context, - uint8_t prk[USHAMaxHashSize], - const unsigned char *info, int info_len, - uint8_t okm[USHAMaxHashSize], int okm_len); #endif /* _SHA_H_ */ diff --git a/src/util/net.c b/src/util/net.c index b2236daf8..ac7befe07 100644 --- a/src/util/net.c +++ b/src/util/net.c @@ -93,121 +93,367 @@ int git_net_url_dup(git_net_url *out, git_net_url *in) return 0; } +static int url_invalid(const char *message) +{ + git_error_set(GIT_ERROR_NET, "invalid url: %s", message); + return GIT_EINVALIDSPEC; +} + +static int url_parse_authority( + const char **user_start, size_t *user_len, + const char **password_start, size_t *password_len, + const char **host_start, size_t *host_len, + const char **port_start, size_t *port_len, + const char *authority_start, size_t len, + const char *scheme_start, size_t scheme_len) +{ + const char *c, *hostport_end, *host_end = NULL, + *userpass_end, *user_end = NULL; + + enum { + HOSTPORT, HOST, IPV6, HOST_END, USERPASS, USER + } state = HOSTPORT; + + if (len == 0) + return 0; + + /* + * walk the authority backwards so that we can parse google code's + * ssh urls that are not rfc compliant and allow @ in the username + */ + for (hostport_end = authority_start + len, c = hostport_end - 1; + c >= authority_start && !user_end; + c--) { + switch (state) { + case HOSTPORT: + if (*c == ':') { + *port_start = c + 1; + *port_len = hostport_end - *port_start; + host_end = c; + state = HOST; + break; + } + + /* + * if we've only seen digits then we don't know + * if we're parsing just a host or a host and port. + * if we see a non-digit, then we're in a host, + * otherwise, fall through to possibly match the + * "@" (user/host separator). + */ + + if (*c < '0' || *c > '9') { + host_end = hostport_end; + state = HOST; + } + + /* fall through */ + + case HOST: + if (*c == ']' && host_end == c + 1) { + host_end = c; + state = IPV6; + } + + else if (*c == '@') { + *host_start = c + 1; + *host_len = host_end ? host_end - *host_start : + hostport_end - *host_start; + userpass_end = c; + state = USERPASS; + } + + else if (*c == '[' || *c == ']' || *c == ':') { + return url_invalid("malformed hostname"); + } + + break; + + case IPV6: + if (*c == '[') { + *host_start = c + 1; + *host_len = host_end - *host_start; + state = HOST_END; + } + + else if ((*c < '0' || *c > '9') && + (*c < 'a' || *c > 'f') && + (*c < 'A' || *c > 'F') && + (*c != ':')) { + return url_invalid("malformed hostname"); + } + + break; + + case HOST_END: + if (*c == '@') { + userpass_end = c; + state = USERPASS; + break; + } + + return url_invalid("malformed hostname"); + + case USERPASS: + if (*c == '@' && + strncasecmp(scheme_start, "ssh", scheme_len)) + return url_invalid("malformed hostname"); + + if (*c == ':') { + *password_start = c + 1; + *password_len = userpass_end - *password_start; + user_end = c; + state = USER; + break; + } + + break; + + default: + GIT_ASSERT(!"unhandled state"); + } + } + + switch (state) { + case HOSTPORT: + *host_start = authority_start; + *host_len = (hostport_end - *host_start); + break; + case HOST: + *host_start = authority_start; + *host_len = (host_end - *host_start); + break; + case IPV6: + return url_invalid("malformed hostname"); + case HOST_END: + break; + case USERPASS: + *user_start = authority_start; + *user_len = (userpass_end - *user_start); + break; + case USER: + *user_start = authority_start; + *user_len = (user_end - *user_start); + break; + default: + GIT_ASSERT(!"unhandled state"); + } + + return 0; +} + int git_net_url_parse(git_net_url *url, const char *given) { - struct http_parser_url u = {0}; - bool has_scheme, has_host, has_port, has_path, has_query, has_userinfo; - git_str scheme = GIT_STR_INIT, - host = GIT_STR_INIT, - port = GIT_STR_INIT, - path = GIT_STR_INIT, - username = GIT_STR_INIT, - password = GIT_STR_INIT, - query = GIT_STR_INIT; - int error = GIT_EINVALIDSPEC; + const char *c, *scheme_start, *authority_start, *user_start, + *password_start, *host_start, *port_start, *path_start, + *query_start, *fragment_start, *default_port; + git_str scheme = GIT_STR_INIT, user = GIT_STR_INIT, + password = GIT_STR_INIT, host = GIT_STR_INIT, + port = GIT_STR_INIT, path = GIT_STR_INIT, + query = GIT_STR_INIT, fragment = GIT_STR_INIT; + size_t scheme_len = 0, user_len = 0, password_len = 0, host_len = 0, + port_len = 0, path_len = 0, query_len = 0, fragment_len = 0; + bool hierarchical = false; + int error = 0; - if (http_parser_parse_url(given, strlen(given), false, &u)) { - git_error_set(GIT_ERROR_NET, "malformed URL '%s'", given); - goto done; + enum { + SCHEME, + AUTHORITY_START, AUTHORITY, + PATH_START, PATH, + QUERY, + FRAGMENT + } state = SCHEME; + + memset(url, 0, sizeof(git_net_url)); + + for (c = scheme_start = given; *c; c++) { + switch (state) { + case SCHEME: + if (*c == ':') { + scheme_len = (c - scheme_start); + + if (*(c+1) == '/' && *(c+2) == '/') { + c += 2; + hierarchical = true; + state = AUTHORITY_START; + } else { + state = PATH_START; + } + } else if ((*c < 'A' || *c > 'Z') && + (*c < 'a' || *c > 'z') && + (*c < '0' || *c > '9') && + (*c != '+' && *c != '-' && *c != '.')) { + /* + * an illegal scheme character means that we + * were just given a relative path + */ + path_start = given; + state = PATH; + break; + } + break; + + case AUTHORITY_START: + authority_start = c; + state = AUTHORITY; + + /* fall through */ + + case AUTHORITY: + if (*c != '/') + break; + + /* + * authority is sufficiently complex that we parse + * it separately + */ + if ((error = url_parse_authority( + &user_start, &user_len, + &password_start,&password_len, + &host_start, &host_len, + &port_start, &port_len, + authority_start, (c - authority_start), + scheme_start, scheme_len)) < 0) + goto done; + + /* fall through */ + + case PATH_START: + path_start = c; + state = PATH; + /* fall through */ + + case PATH: + switch (*c) { + case '?': + path_len = (c - path_start); + query_start = c + 1; + state = QUERY; + break; + case '#': + path_len = (c - path_start); + fragment_start = c + 1; + state = FRAGMENT; + break; + } + break; + + case QUERY: + if (*c == '#') { + query_len = (c - query_start); + fragment_start = c + 1; + state = FRAGMENT; + } + break; + + case FRAGMENT: + break; + + default: + GIT_ASSERT(!"unhandled state"); + } } - has_scheme = !!(u.field_set & (1 << UF_SCHEMA)); - has_host = !!(u.field_set & (1 << UF_HOST)); - has_port = !!(u.field_set & (1 << UF_PORT)); - has_path = !!(u.field_set & (1 << UF_PATH)); - has_query = !!(u.field_set & (1 << UF_QUERY)); - has_userinfo = !!(u.field_set & (1 << UF_USERINFO)); - - if (has_scheme) { - const char *url_scheme = given + u.field_data[UF_SCHEMA].off; - size_t url_scheme_len = u.field_data[UF_SCHEMA].len; - git_str_put(&scheme, url_scheme, url_scheme_len); - git__strntolower(scheme.ptr, scheme.size); - } else { - git_error_set(GIT_ERROR_NET, "malformed URL '%s'", given); - goto done; - } - - if (has_host) { - const char *url_host = given + u.field_data[UF_HOST].off; - size_t url_host_len = u.field_data[UF_HOST].len; - git_str_decode_percent(&host, url_host, url_host_len); - } - - if (has_port) { - const char *url_port = given + u.field_data[UF_PORT].off; - size_t url_port_len = u.field_data[UF_PORT].len; - git_str_put(&port, url_port, url_port_len); - } else { - const char *default_port = default_port_for_scheme(scheme.ptr); - - if (default_port == NULL) { - git_error_set(GIT_ERROR_NET, "unknown scheme for URL '%s'", given); + switch (state) { + case SCHEME: + /* + * if we never saw a ':' then we were given a relative + * path, not a bare scheme + */ + path_start = given; + path_len = (c - scheme_start); + break; + case AUTHORITY_START: + break; + case AUTHORITY: + if ((error = url_parse_authority( + &user_start, &user_len, + &password_start,&password_len, + &host_start, &host_len, + &port_start, &port_len, + authority_start, (c - authority_start), + scheme_start, scheme_len)) < 0) goto done; - } - - git_str_puts(&port, default_port); + break; + case PATH_START: + break; + case PATH: + path_len = (c - path_start); + break; + case QUERY: + query_len = (c - query_start); + break; + case FRAGMENT: + fragment_len = (c - fragment_start); + break; + default: + GIT_ASSERT(!"unhandled state"); } - if (has_path) { - const char *url_path = given + u.field_data[UF_PATH].off; - size_t url_path_len = u.field_data[UF_PATH].len; - git_str_put(&path, url_path, url_path_len); - } else { - git_str_puts(&path, "/"); + if (scheme_len) { + if ((error = git_str_put(&scheme, scheme_start, scheme_len)) < 0) + goto done; + + git__strntolower(scheme.ptr, scheme.size); } - if (has_query) { - const char *url_query = given + u.field_data[UF_QUERY].off; - size_t url_query_len = u.field_data[UF_QUERY].len; - git_str_decode_percent(&query, url_query, url_query_len); - } + if (user_len && + (error = git_str_decode_percent(&user, user_start, user_len)) < 0) + goto done; - if (has_userinfo) { - const char *url_userinfo = given + u.field_data[UF_USERINFO].off; - size_t url_userinfo_len = u.field_data[UF_USERINFO].len; - const char *colon = memchr(url_userinfo, ':', url_userinfo_len); + if (password_len && + (error = git_str_decode_percent(&password, password_start, password_len)) < 0) + goto done; - if (colon) { - const char *url_username = url_userinfo; - size_t url_username_len = colon - url_userinfo; - const char *url_password = colon + 1; - size_t url_password_len = url_userinfo_len - (url_username_len + 1); + if (host_len && + (error = git_str_decode_percent(&host, host_start, host_len)) < 0) + goto done; - git_str_decode_percent(&username, url_username, url_username_len); - git_str_decode_percent(&password, url_password, url_password_len); - } else { - git_str_decode_percent(&username, url_userinfo, url_userinfo_len); - } - } + if (port_len) + error = git_str_put(&port, port_start, port_len); + else if (scheme_len && (default_port = default_port_for_scheme(scheme.ptr)) != NULL) + error = git_str_puts(&port, default_port); - if (git_str_oom(&scheme) || - git_str_oom(&host) || - git_str_oom(&port) || - git_str_oom(&path) || - git_str_oom(&query) || - git_str_oom(&username) || - git_str_oom(&password)) - return -1; + if (error < 0) + goto done; + + if (path_len) + error = git_str_put(&path, path_start, path_len); + else if (hierarchical) + error = git_str_puts(&path, "/"); + + if (error < 0) + goto done; + + if (query_len && + (error = git_str_decode_percent(&query, query_start, query_len)) < 0) + goto done; + + if (fragment_len && + (error = git_str_decode_percent(&fragment, fragment_start, fragment_len)) < 0) + goto done; url->scheme = git_str_detach(&scheme); url->host = git_str_detach(&host); url->port = git_str_detach(&port); url->path = git_str_detach(&path); url->query = git_str_detach(&query); - url->username = git_str_detach(&username); + url->fragment = git_str_detach(&fragment); + url->username = git_str_detach(&user); url->password = git_str_detach(&password); error = 0; done: git_str_dispose(&scheme); + git_str_dispose(&user); + git_str_dispose(&password); git_str_dispose(&host); git_str_dispose(&port); git_str_dispose(&path); git_str_dispose(&query); - git_str_dispose(&username); - git_str_dispose(&password); + git_str_dispose(&fragment); + return error; } @@ -374,7 +620,7 @@ int git_net_url_parse_scp(git_net_url *url, const char *given) break; default: - GIT_ASSERT("unhandled state"); + GIT_ASSERT(!"unhandled state"); } } @@ -400,6 +646,13 @@ int git_net_url_parse_scp(git_net_url *url, const char *given) return 0; } +int git_net_url_parse_standard_or_scp(git_net_url *url, const char *given) +{ + return git_net_str_is_url(given) ? + git_net_url_parse(url, given) : + git_net_url_parse_scp(url, given); +} + int git_net_url_joinpath( git_net_url *out, git_net_url *one, @@ -588,7 +841,7 @@ bool git_net_url_is_default_port(git_net_url *url) { const char *default_port; - if ((default_port = default_port_for_scheme(url->scheme)) != NULL) + if (url->scheme && (default_port = default_port_for_scheme(url->scheme)) != NULL) return (strcmp(url->port, default_port) == 0); else return false; @@ -744,6 +997,7 @@ void git_net_url_dispose(git_net_url *url) git__free(url->port); url->port = NULL; git__free(url->path); url->path = NULL; git__free(url->query); url->query = NULL; + git__free(url->fragment); url->fragment = NULL; git__free(url->username); url->username = NULL; git__free(url->password); url->password = NULL; } diff --git a/src/util/net.h b/src/util/net.h index 88030a952..17f0bc4f0 100644 --- a/src/util/net.h +++ b/src/util/net.h @@ -15,6 +15,7 @@ typedef struct git_net_url { char *port; char *path; char *query; + char *fragment; char *username; char *password; } git_net_url; @@ -33,6 +34,12 @@ extern int git_net_url_parse(git_net_url *url, const char *str); /** Parses a string containing an SCP style path into a URL structure. */ extern int git_net_url_parse_scp(git_net_url *url, const char *str); +/** + * Parses a string containing a standard URL or an SCP style path into + * a URL structure. + */ +extern int git_net_url_parse_standard_or_scp(git_net_url *url, const char *str); + /** Appends a path and/or query string to the given URL */ extern int git_net_url_joinpath( git_net_url *out, diff --git a/src/util/posix.h b/src/util/posix.h index c8f8cd9d2..607aa9dce 100644 --- a/src/util/posix.h +++ b/src/util/posix.h @@ -104,6 +104,8 @@ typedef __int64 off64_t; typedef __haiku_std_int64 off64_t; #elif defined(__APPLE__) typedef __int64_t off64_t; +#elif defined(_AIX) +typedef long long off64_t; #else typedef int64_t off64_t; #endif diff --git a/src/util/rand.c b/src/util/rand.c index d28e4aa97..940faf947 100644 --- a/src/util/rand.c +++ b/src/util/rand.c @@ -14,6 +14,10 @@ See . */ # include #endif +#if defined(GIT_WIN32) +# include +#endif + static uint64_t state[4]; static git_mutex state_lock; diff --git a/src/util/regexp.c b/src/util/regexp.c index 2569dea0a..08700882b 100644 --- a/src/util/regexp.c +++ b/src/util/regexp.c @@ -108,11 +108,11 @@ int git_regexp_match(const git_regexp *r, const char *string) data = pcre2_match_data_create(1, NULL); GIT_ERROR_CHECK_ALLOC(data); - if ((error = pcre2_match(*r, (const unsigned char *) string, strlen(string), - 0, 0, data, NULL)) < 0) + error = pcre2_match(*r, (const unsigned char *) string, strlen(string), 0, 0, data, NULL); + pcre2_match_data_free(data); + if (error < 0) return (error == PCRE2_ERROR_NOMATCH) ? GIT_ENOTFOUND : GIT_EINVALIDSPEC; - pcre2_match_data_free(data); return 0; } diff --git a/src/util/thread.h b/src/util/thread.h index 4bbac9fd8..c32554bfd 100644 --- a/src/util/thread.h +++ b/src/util/thread.h @@ -260,36 +260,37 @@ GIT_INLINE(int64_t) git_atomic64_get(git_atomic64 *a) #else -#define git_threads_global_init git__noop +#define git_threads_global_init git__noop #define git_thread unsigned int -#define git_thread_create(thread, start_routine, arg) git__noop() -#define git_thread_join(id, status) git__noop() +#define git_thread_create(t, s, a) git__noop(t, s, a) +#define git_thread_join(i, s) git__noop_args(i, s) /* Pthreads Mutex */ #define git_mutex unsigned int -#define git_mutex_init(a) git__noop() -#define git_mutex_init(a) git__noop() -#define git_mutex_lock(a) git__noop() -#define git_mutex_unlock(a) git__noop() -#define git_mutex_free(a) git__noop() +#define git_mutex_init(a) git__noop_args(a) +#define git_mutex_init(a) git__noop_args(a) +#define git_mutex_lock(a) git__noop_args(a) +#define git_mutex_unlock(a) git__noop_args(a) +#define git_mutex_free(a) git__noop_args(a) /* Pthreads condition vars */ #define git_cond unsigned int -#define git_cond_init(c) git__noop() -#define git_cond_free(c) git__noop() -#define git_cond_wait(c, l) git__noop() -#define git_cond_signal(c) git__noop() -#define git_cond_broadcast(c) git__noop() +#define git_cond_init(c) git__noop_args(c) +#define git_cond_free(c) git__noop_args(c) +#define git_cond_wait(c, l) git__noop_args(c, l) +#define git_cond_signal(c) git__noop_args(c) +#define git_cond_broadcast(c) git__noop_args(c) /* Pthreads rwlock */ #define git_rwlock unsigned int -#define git_rwlock_init(a) git__noop() -#define git_rwlock_rdlock(a) git__noop() -#define git_rwlock_rdunlock(a) git__noop() -#define git_rwlock_wrlock(a) git__noop() -#define git_rwlock_wrunlock(a) git__noop() -#define git_rwlock_free(a) git__noop() +#define git_rwlock_init(a) git__noop_args(a) +#define git_rwlock_rdlock(a) git__noop_args(a) +#define git_rwlock_rdunlock(a) git__noop_args(a) +#define git_rwlock_wrlock(a) git__noop_args(a) +#define git_rwlock_wrunlock(a) git__noop_args(a) +#define git_rwlock_free(a) git__noop_args(a) + #define GIT_RWLOCK_STATIC_INIT 0 diff --git a/src/util/util.h b/src/util/util.h index 8d6d1d6b6..63d6080f7 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -381,6 +381,7 @@ extern int git__getenv(git_str *out, const char *name); extern int git__online_cpus(void); GIT_INLINE(int) git__noop(void) { return 0; } +GIT_INLINE(int) git__noop_args(void *a, ...) { GIT_UNUSED(a); return 0; } #include "alloc.h" diff --git a/src/util/win32/findfile.c b/src/util/win32/findfile.c deleted file mode 100644 index 725a90167..000000000 --- a/src/util/win32/findfile.c +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ - -#include "findfile.h" - -#include "path_w32.h" -#include "utf-conv.h" -#include "fs_path.h" - -#define REG_GITFORWINDOWS_KEY L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Git_is1" -#define REG_GITFORWINDOWS_KEY_WOW64 L"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Git_is1" - -static int git_win32__expand_path(git_win32_path dest, const wchar_t *src) -{ - DWORD len = ExpandEnvironmentStringsW(src, dest, GIT_WIN_PATH_UTF16); - - if (!len || len > GIT_WIN_PATH_UTF16) - return -1; - - return 0; -} - -static int win32_path_to_8(git_str *dest, const wchar_t *src) -{ - git_win32_utf8_path utf8_path; - - if (git_win32_path_to_utf8(utf8_path, src) < 0) { - git_error_set(GIT_ERROR_OS, "unable to convert path to UTF-8"); - return -1; - } - - /* Convert backslashes to forward slashes */ - git_fs_path_mkposix(utf8_path); - - return git_str_sets(dest, utf8_path); -} - -static git_win32_path mock_registry; -static bool mock_registry_set; - -extern int git_win32__set_registry_system_dir(const wchar_t *mock_sysdir) -{ - if (!mock_sysdir) { - mock_registry[0] = L'\0'; - mock_registry_set = false; - } else { - size_t len = wcslen(mock_sysdir); - - if (len > GIT_WIN_PATH_MAX) { - git_error_set(GIT_ERROR_INVALID, "mock path too long"); - return -1; - } - - wcscpy(mock_registry, mock_sysdir); - mock_registry_set = true; - } - - return 0; -} - -static int lookup_registry_key( - git_win32_path out, - const HKEY hive, - const wchar_t* key, - const wchar_t *value) -{ - HKEY hkey; - DWORD type, size; - int error = GIT_ENOTFOUND; - - /* - * Registry data may not be NUL terminated, provide room to do - * it ourselves. - */ - size = (DWORD)((sizeof(git_win32_path) - 1) * sizeof(wchar_t)); - - if (RegOpenKeyExW(hive, key, 0, KEY_READ, &hkey) != 0) - return GIT_ENOTFOUND; - - if (RegQueryValueExW(hkey, value, NULL, &type, (LPBYTE)out, &size) == 0 && - type == REG_SZ && - size > 0 && - size < sizeof(git_win32_path)) { - size_t wsize = size / sizeof(wchar_t); - size_t len = wsize - 1; - - if (out[wsize - 1] != L'\0') { - len = wsize; - out[wsize] = L'\0'; - } - - if (out[len - 1] == L'\\') - out[len - 1] = L'\0'; - - if (_waccess(out, F_OK) == 0) - error = 0; - } - - RegCloseKey(hkey); - return error; -} - -static int find_sysdir_in_registry(git_win32_path out) -{ - if (mock_registry_set) { - if (mock_registry[0] == L'\0') - return GIT_ENOTFOUND; - - wcscpy(out, mock_registry); - return 0; - } - - if (lookup_registry_key(out, HKEY_CURRENT_USER, REG_GITFORWINDOWS_KEY, L"InstallLocation") == 0 || - lookup_registry_key(out, HKEY_CURRENT_USER, REG_GITFORWINDOWS_KEY_WOW64, L"InstallLocation") == 0 || - lookup_registry_key(out, HKEY_LOCAL_MACHINE, REG_GITFORWINDOWS_KEY, L"InstallLocation") == 0 || - lookup_registry_key(out, HKEY_LOCAL_MACHINE, REG_GITFORWINDOWS_KEY_WOW64, L"InstallLocation") == 0) - return 0; - - return GIT_ENOTFOUND; -} - -static int find_sysdir_in_path(git_win32_path out) -{ - size_t out_len; - - if (git_win32_path_find_executable(out, L"git.exe") < 0 && - git_win32_path_find_executable(out, L"git.cmd") < 0) - return GIT_ENOTFOUND; - - out_len = wcslen(out); - - /* Trim the file name */ - if (out_len <= CONST_STRLEN(L"git.exe")) - return GIT_ENOTFOUND; - - out_len -= CONST_STRLEN(L"git.exe"); - - if (out_len && out[out_len - 1] == L'\\') - out_len--; - - /* - * Git for Windows usually places the command in a 'bin' or - * 'cmd' directory, trim that. - */ - if (out_len >= CONST_STRLEN(L"\\bin") && - wcsncmp(&out[out_len - CONST_STRLEN(L"\\bin")], L"\\bin", CONST_STRLEN(L"\\bin")) == 0) - out_len -= CONST_STRLEN(L"\\bin"); - else if (out_len >= CONST_STRLEN(L"\\cmd") && - wcsncmp(&out[out_len - CONST_STRLEN(L"\\cmd")], L"\\cmd", CONST_STRLEN(L"\\cmd")) == 0) - out_len -= CONST_STRLEN(L"\\cmd"); - - if (!out_len) - return GIT_ENOTFOUND; - - out[out_len] = L'\0'; - return 0; -} - -static int win32_find_existing_dirs( - git_str* out, - const wchar_t* tmpl[]) -{ - git_win32_path path16; - git_str buf = GIT_STR_INIT; - - git_str_clear(out); - - for (; *tmpl != NULL; tmpl++) { - if (!git_win32__expand_path(path16, *tmpl) && - path16[0] != L'%' && - !_waccess(path16, F_OK)) { - win32_path_to_8(&buf, path16); - - if (buf.size) - git_str_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr); - } - } - - git_str_dispose(&buf); - - return (git_str_oom(out) ? -1 : 0); -} - -static int append_subdir(git_str *out, git_str *path, const char *subdir) -{ - static const char* architecture_roots[] = { - "", - "mingw64", - "mingw32", - NULL - }; - const char **root; - size_t orig_path_len = path->size; - - for (root = architecture_roots; *root; root++) { - if ((*root[0] && git_str_joinpath(path, path->ptr, *root) < 0) || - git_str_joinpath(path, path->ptr, subdir) < 0) - return -1; - - if (git_fs_path_exists(path->ptr) && - git_str_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, path->ptr) < 0) - return -1; - - git_str_truncate(path, orig_path_len); - } - - return 0; -} - -int git_win32__find_system_dirs(git_str *out, const char *subdir) -{ - git_win32_path pathdir, regdir; - git_str path8 = GIT_STR_INIT; - bool has_pathdir, has_regdir; - int error; - - has_pathdir = (find_sysdir_in_path(pathdir) == 0); - has_regdir = (find_sysdir_in_registry(regdir) == 0); - - if (!has_pathdir && !has_regdir) - return 0; - - /* - * Usually the git in the path is the same git in the registry, - * in this case there's no need to duplicate the paths. - */ - if (has_pathdir && has_regdir && wcscmp(pathdir, regdir) == 0) - has_regdir = false; - - if (has_pathdir) { - if ((error = win32_path_to_8(&path8, pathdir)) < 0 || - (error = append_subdir(out, &path8, subdir)) < 0) - goto done; - } - - if (has_regdir) { - if ((error = win32_path_to_8(&path8, regdir)) < 0 || - (error = append_subdir(out, &path8, subdir)) < 0) - goto done; - } - -done: - git_str_dispose(&path8); - return error; -} - -int git_win32__find_global_dirs(git_str *out) -{ - static const wchar_t *global_tmpls[4] = { - L"%HOME%\\", - L"%HOMEDRIVE%%HOMEPATH%\\", - L"%USERPROFILE%\\", - NULL, - }; - - return win32_find_existing_dirs(out, global_tmpls); -} - -int git_win32__find_xdg_dirs(git_str *out) -{ - static const wchar_t *global_tmpls[7] = { - L"%XDG_CONFIG_HOME%\\git", - L"%APPDATA%\\git", - L"%LOCALAPPDATA%\\git", - L"%HOME%\\.config\\git", - L"%HOMEDRIVE%%HOMEPATH%\\.config\\git", - L"%USERPROFILE%\\.config\\git", - NULL, - }; - - return win32_find_existing_dirs(out, global_tmpls); -} - -int git_win32__find_programdata_dirs(git_str *out) -{ - static const wchar_t *programdata_tmpls[2] = { - L"%PROGRAMDATA%\\Git", - NULL, - }; - - return win32_find_existing_dirs(out, programdata_tmpls); -} diff --git a/src/util/win32/findfile.h b/src/util/win32/findfile.h deleted file mode 100644 index 7b191d1fe..000000000 --- a/src/util/win32/findfile.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ - -#ifndef INCLUDE_win32_findfile_h__ -#define INCLUDE_win32_findfile_h__ - -#include "git2_util.h" - -/** Sets the mock registry root for Git for Windows for testing. */ -extern int git_win32__set_registry_system_dir(const wchar_t *mock_sysdir); - -extern int git_win32__find_system_dirs(git_str *out, const char *subpath); -extern int git_win32__find_global_dirs(git_str *out); -extern int git_win32__find_xdg_dirs(git_str *out); -extern int git_win32__find_programdata_dirs(git_str *out); - -#endif - diff --git a/tests/clar/clar.c b/tests/clar/clar.c index ca508d073..c9c3fde38 100644 --- a/tests/clar/clar.c +++ b/tests/clar/clar.c @@ -12,6 +12,7 @@ #include #include #include +#include /* required for sandboxing */ #include @@ -86,6 +87,8 @@ typedef struct stat STAT_T; #endif +#define MAX(x, y) (((x) > (y)) ? (x) : (y)) + #include "clar.h" static void fs_rm(const char *_source); @@ -117,6 +120,8 @@ struct clar_report { const char *suite; enum cl_test_status status; + time_t start; + double elapsed; struct clar_error *errors; struct clar_error *last_error; @@ -145,7 +150,7 @@ static struct { int report_errors_only; int exit_on_error; - int report_suite_names; + int verbosity; int write_summary; char *summary_filename; @@ -186,7 +191,7 @@ struct clar_suite { static void clar_print_init(int test_count, int suite_count, const char *suite_names); static void clar_print_shutdown(int test_count, int suite_count, int error_count); static void clar_print_error(int num, const struct clar_report *report, const struct clar_error *error); -static void clar_print_ontest(const char *test_name, int test_number, enum cl_test_status failed); +static void clar_print_ontest(const char *suite_name, const char *test_name, int test_number, enum cl_test_status failed); static void clar_print_onsuite(const char *suite_name, int suite_index); static void clar_print_onabort(const char *msg, ...); @@ -245,16 +250,53 @@ clar_report_all(void) } } +#ifdef WIN32 +# define clar_time DWORD + +static void clar_time_now(clar_time *out) +{ + *out = GetTickCount(); +} + +static double clar_time_diff(clar_time *start, clar_time *end) +{ + return ((double)*end - (double)*start) / 1000; +} +#else +# include + +# define clar_time struct timeval + +static void clar_time_now(clar_time *out) +{ + struct timezone tz; + + gettimeofday(out, &tz); +} + +static double clar_time_diff(clar_time *start, clar_time *end) +{ + return ((double)end->tv_sec + (double)end->tv_usec / 1.0E6) - + ((double)start->tv_sec + (double)start->tv_usec / 1.0E6); +} +#endif + static void clar_run_test( + const struct clar_suite *suite, const struct clar_func *test, const struct clar_func *initialize, const struct clar_func *cleanup) { + clar_time start, end; + _clar.trampoline_enabled = 1; CL_TRACE(CL_TRACE__TEST__BEGIN); + _clar.last_report->start = time(NULL); + clar_time_now(&start); + if (setjmp(_clar.trampoline) == 0) { if (initialize->ptr != NULL) initialize->ptr(); @@ -264,11 +306,15 @@ clar_run_test( CL_TRACE(CL_TRACE__TEST__RUN_END); } + clar_time_now(&end); + _clar.trampoline_enabled = 0; if (_clar.last_report->status == CL_TEST_NOTRUN) _clar.last_report->status = CL_TEST_OK; + _clar.last_report->elapsed = clar_time_diff(&start, &end); + if (_clar.local_cleanup != NULL) _clar.local_cleanup(_clar.local_cleanup_payload); @@ -286,7 +332,7 @@ clar_run_test( if (_clar.report_errors_only) { clar_report_errors(_clar.last_report); } else { - clar_print_ontest(test->name, _clar.tests_ran, _clar.last_report->status); + clar_print_ontest(suite->name, test->name, _clar.tests_ran, _clar.last_report->status); } } @@ -352,7 +398,7 @@ clar_run_suite(const struct clar_suite *suite, const char *filter) _clar.last_report = report; - clar_run_test(&test[i], &suite->initialize, &suite->cleanup); + clar_run_test(suite, &test[i], &suite->initialize, &suite->cleanup); if (_clar.exit_on_error && _clar.total_errors) return; @@ -427,7 +473,7 @@ clar_parse_args(int argc, char **argv) ++found; if (!exact) - _clar.report_suite_names = 1; + _clar.verbosity = MAX(_clar.verbosity, 1); switch (action) { case 's': { @@ -486,13 +532,13 @@ clar_parse_args(int argc, char **argv) } case 'v': - _clar.report_suite_names = 1; + _clar.verbosity++; break; case 'r': _clar.write_summary = 1; free(_clar.summary_filename); - _clar.summary_filename = strdup(*(argument + 2) ? (argument + 2) : "summary.xml"); + _clar.summary_filename = *(argument + 2) ? strdup(argument + 2) : NULL; break; default: @@ -504,6 +550,8 @@ clar_parse_args(int argc, char **argv) void clar_test_init(int argc, char **argv) { + const char *summary_env; + if (argc > 1) clar_parse_args(argc, argv); @@ -513,11 +561,15 @@ clar_test_init(int argc, char **argv) "" ); - if ((_clar.summary_filename = getenv("CLAR_SUMMARY")) != NULL) { + if (!_clar.summary_filename && + (summary_env = getenv("CLAR_SUMMARY")) != NULL) { _clar.write_summary = 1; - _clar.summary_filename = strdup(_clar.summary_filename); + _clar.summary_filename = strdup(summary_env); } + if (_clar.write_summary && !_clar.summary_filename) + _clar.summary_filename = strdup("summary.xml"); + if (_clar.write_summary && !(_clar.summary = clar_summary_init(_clar.summary_filename))) { clar_print_onabort("Failed to open the summary file\n"); diff --git a/tests/clar/clar.h b/tests/clar/clar.h index 3f659c2f6..8c22382bd 100644 --- a/tests/clar/clar.h +++ b/tests/clar/clar.h @@ -13,12 +13,12 @@ enum cl_test_status { CL_TEST_OK, CL_TEST_FAILURE, CL_TEST_SKIP, - CL_TEST_NOTRUN + CL_TEST_NOTRUN, }; enum cl_output_format { CL_OUTPUT_CLAP, - CL_OUTPUT_TAP + CL_OUTPUT_TAP, }; /** Setup clar environment */ @@ -60,7 +60,7 @@ typedef enum cl_trace_event { CL_TRACE__TEST__END, CL_TRACE__TEST__RUN_BEGIN, CL_TRACE__TEST__RUN_END, - CL_TRACE__TEST__LONGJMP + CL_TRACE__TEST__LONGJMP, } cl_trace_event; typedef void (cl_trace_cb)( diff --git a/tests/clar/clar/print.h b/tests/clar/clar/print.h index dbfd27655..c17e2f693 100644 --- a/tests/clar/clar/print.h +++ b/tests/clar/clar/print.h @@ -36,24 +36,35 @@ static void clar_print_clap_error(int num, const struct clar_report *report, con fflush(stdout); } -static void clar_print_clap_ontest(const char *test_name, int test_number, enum cl_test_status status) +static void clar_print_clap_ontest(const char *suite_name, const char *test_name, int test_number, enum cl_test_status status) { (void)test_name; (void)test_number; - switch(status) { - case CL_TEST_OK: printf("."); break; - case CL_TEST_FAILURE: printf("F"); break; - case CL_TEST_SKIP: printf("S"); break; - case CL_TEST_NOTRUN: printf("N"); break; - } + if (_clar.verbosity > 1) { + printf("%s::%s: ", suite_name, test_name); - fflush(stdout); + switch (status) { + case CL_TEST_OK: printf("ok\n"); break; + case CL_TEST_FAILURE: printf("fail\n"); break; + case CL_TEST_SKIP: printf("skipped"); break; + case CL_TEST_NOTRUN: printf("notrun"); break; + } + } else { + switch (status) { + case CL_TEST_OK: printf("."); break; + case CL_TEST_FAILURE: printf("F"); break; + case CL_TEST_SKIP: printf("S"); break; + case CL_TEST_NOTRUN: printf("N"); break; + } + + fflush(stdout); + } } static void clar_print_clap_onsuite(const char *suite_name, int suite_index) { - if (_clar.report_suite_names) + if (_clar.verbosity == 1) printf("\n%s", suite_name); (void)suite_index; @@ -102,7 +113,7 @@ static void print_escaped(const char *str) printf("%s", str); } -static void clar_print_tap_ontest(const char *test_name, int test_number, enum cl_test_status status) +static void clar_print_tap_ontest(const char *suite_name, const char *test_name, int test_number, enum cl_test_status status) { const struct clar_error *error = _clar.last_report->errors; @@ -111,10 +122,10 @@ static void clar_print_tap_ontest(const char *test_name, int test_number, enum c switch(status) { case CL_TEST_OK: - printf("ok %d - %s::%s\n", test_number, _clar.active_suite, test_name); + printf("ok %d - %s::%s\n", test_number, suite_name, test_name); break; case CL_TEST_FAILURE: - printf("not ok %d - %s::%s\n", test_number, _clar.active_suite, test_name); + printf("not ok %d - %s::%s\n", test_number, suite_name, test_name); printf(" ---\n"); printf(" reason: |\n"); @@ -132,7 +143,7 @@ static void clar_print_tap_ontest(const char *test_name, int test_number, enum c break; case CL_TEST_SKIP: case CL_TEST_NOTRUN: - printf("ok %d - # SKIP %s::%s\n", test_number, _clar.active_suite, test_name); + printf("ok %d - # SKIP %s::%s\n", test_number, suite_name, test_name); break; } @@ -181,9 +192,9 @@ static void clar_print_error(int num, const struct clar_report *report, const st PRINT(error, num, report, error); } -static void clar_print_ontest(const char *test_name, int test_number, enum cl_test_status status) +static void clar_print_ontest(const char *suite_name, const char *test_name, int test_number, enum cl_test_status status) { - PRINT(ontest, test_name, test_number, status); + PRINT(ontest, suite_name, test_name, test_number, status); } static void clar_print_onsuite(const char *suite_name, int suite_index) diff --git a/tests/clar/clar/summary.h b/tests/clar/clar/summary.h index 6279f5057..4dd352e28 100644 --- a/tests/clar/clar/summary.h +++ b/tests/clar/clar/summary.h @@ -20,8 +20,8 @@ static int clar_summary_testsuites(struct clar_summary *summary) } static int clar_summary_testsuite(struct clar_summary *summary, - int idn, const char *name, const char *pkg, time_t timestamp, - double elapsed, int test_count, int fail_count, int error_count) + int idn, const char *name, time_t timestamp, + int test_count, int fail_count, int error_count) { struct tm *tm = localtime(×tamp); char iso_dt[20]; @@ -29,17 +29,15 @@ static int clar_summary_testsuite(struct clar_summary *summary, if (strftime(iso_dt, sizeof(iso_dt), "%Y-%m-%dT%H:%M:%S", tm) == 0) return -1; - return fprintf(summary->fp, "\tfp, "\t\n", - idn, name, pkg, iso_dt, elapsed, test_count, fail_count, error_count); + idn, name, iso_dt, test_count, fail_count, error_count); } static int clar_summary_testcase(struct clar_summary *summary, @@ -58,15 +56,23 @@ static int clar_summary_failure(struct clar_summary *summary, type, message, desc); } +static int clar_summary_skipped(struct clar_summary *summary) +{ + return fprintf(summary->fp, "\t\t\t\n"); +} + struct clar_summary *clar_summary_init(const char *filename) { struct clar_summary *summary; FILE *fp; - if ((fp = fopen(filename, "w")) == NULL) + if ((fp = fopen(filename, "w")) == NULL) { + perror("fopen"); return NULL; + } if ((summary = malloc(sizeof(struct clar_summary))) == NULL) { + perror("malloc"); fclose(fp); return NULL; } @@ -90,14 +96,14 @@ int clar_summary_shutdown(struct clar_summary *summary) struct clar_error *error = report->errors; if (last_suite == NULL || strcmp(last_suite, report->suite) != 0) { - if (clar_summary_testsuite(summary, 0, report->suite, "", - time(NULL), 0, _clar.tests_ran, _clar.total_errors, 0) < 0) + if (clar_summary_testsuite(summary, 0, report->suite, + report->start, _clar.tests_ran, _clar.total_errors, 0) < 0) goto on_error; } last_suite = report->suite; - clar_summary_testcase(summary, report->test, "what", 0); + clar_summary_testcase(summary, report->test, report->suite, report->elapsed); while (error != NULL) { if (clar_summary_failure(summary, "assert", @@ -107,6 +113,9 @@ int clar_summary_shutdown(struct clar_summary *summary) error = error->next; } + if (report->status == CL_TEST_SKIP) + clar_summary_skipped(summary); + if (clar_summary_close_tag(summary, "testcase", 2) < 0) goto on_error; diff --git a/tests/clar/clar_libgit2.c b/tests/clar/clar_libgit2.c index 783b457f9..54122997d 100644 --- a/tests/clar/clar_libgit2.c +++ b/tests/clar/clar_libgit2.c @@ -1,6 +1,7 @@ #include "clar_libgit2.h" #include "posix.h" #include "fs_path.h" +#include "futils.h" #include "git2/sys/repository.h" void cl_git_report_failure( @@ -476,6 +477,25 @@ int cl_repo_get_bool(git_repository *repo, const char *cfg) return val; } +void cl_repo_set_int(git_repository *repo, const char *cfg, int value) +{ + git_config *config; + cl_git_pass(git_repository_config(&config, repo)); + cl_git_pass(git_config_set_int32(config, cfg, value)); + git_config_free(config); +} + +int cl_repo_get_int(git_repository *repo, const char *cfg) +{ + int val = 0; + git_config *config; + cl_git_pass(git_repository_config(&config, repo)); + if (git_config_get_int32(&val, config, cfg) < 0) + git_error_clear(); + git_config_free(config); + return val; +} + void cl_repo_set_string(git_repository *repo, const char *cfg, const char *value) { git_config *config; @@ -548,33 +568,95 @@ void clar__assert_equal_file( (size_t)expected_bytes, (size_t)total_bytes); } -static git_buf _cl_restore_home = GIT_BUF_INIT; +#define FAKE_HOMEDIR_NAME "cl_fake_home" -void cl_fake_home_cleanup(void *payload) +static git_buf _cl_restore_homedir = GIT_BUF_INIT; + +void cl_fake_homedir_cleanup(void *payload) { GIT_UNUSED(payload); - if (_cl_restore_home.ptr) { - cl_git_pass(git_libgit2_opts( - GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, _cl_restore_home.ptr)); - git_buf_dispose(&_cl_restore_home); + if (_cl_restore_homedir.ptr) { + cl_git_pass(git_futils_rmdir_r(FAKE_HOMEDIR_NAME, NULL, GIT_RMDIR_REMOVE_FILES)); + + cl_git_pass(git_libgit2_opts(GIT_OPT_SET_HOMEDIR, _cl_restore_homedir.ptr)); + git_buf_dispose(&_cl_restore_homedir); } } -void cl_fake_home(void) +void cl_fake_homedir(git_str *out) { git_str path = GIT_STR_INIT; cl_git_pass(git_libgit2_opts( - GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, &_cl_restore_home)); + GIT_OPT_GET_HOMEDIR, &_cl_restore_homedir)); - cl_set_cleanup(cl_fake_home_cleanup, NULL); + cl_set_cleanup(cl_fake_homedir_cleanup, NULL); + + /* TOC/TOU but merely attempts to prevent accidental cleanup. */ + cl_assert(!git_fs_path_exists(FAKE_HOMEDIR_NAME)); + cl_must_pass(p_mkdir(FAKE_HOMEDIR_NAME, 0777)); + cl_git_pass(git_fs_path_prettify(&path, FAKE_HOMEDIR_NAME, NULL)); + cl_git_pass(git_libgit2_opts(GIT_OPT_SET_HOMEDIR, path.ptr)); + + if (out) + git_str_swap(out, &path); + + git_str_dispose(&path); +} + +#define FAKE_GLOBALCONFIG_NAME "cl_fake_global" + +static git_buf _cl_restore_globalconfig = GIT_BUF_INIT; + +void cl_fake_globalconfig_cleanup(void *payload) +{ + GIT_UNUSED(payload); + + if (_cl_restore_globalconfig.ptr) { + cl_git_pass(git_futils_rmdir_r(FAKE_GLOBALCONFIG_NAME, NULL, GIT_RMDIR_REMOVE_FILES)); + + cl_git_pass(git_libgit2_opts(GIT_OPT_SET_HOMEDIR, _cl_restore_globalconfig.ptr)); + git_buf_dispose(&_cl_restore_globalconfig); + } +} + +void cl_fake_globalconfig(git_str *out) +{ + git_str path = GIT_STR_INIT; - if (!git_fs_path_exists("home")) - cl_must_pass(p_mkdir("home", 0777)); - cl_git_pass(git_fs_path_prettify(&path, "home", NULL)); cl_git_pass(git_libgit2_opts( - GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr)); + GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, &_cl_restore_globalconfig)); + + cl_set_cleanup(cl_fake_globalconfig_cleanup, NULL); + + /* TOC/TOU but merely attempts to prevent accidental cleanup. */ + cl_assert(!git_fs_path_exists(FAKE_GLOBALCONFIG_NAME)); + cl_must_pass(p_mkdir(FAKE_GLOBALCONFIG_NAME, 0777)); + cl_git_pass(git_fs_path_prettify(&path, FAKE_GLOBALCONFIG_NAME, NULL)); + cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr)); + + if (out) + git_str_swap(out, &path); + + git_str_dispose(&path); +} + +void cl_sandbox_set_homedir(const char *home) +{ + git_str path = GIT_STR_INIT; + + if (home) { + git_libgit2_opts(GIT_OPT_SET_HOMEDIR, home); + } else { + git_str_joinpath(&path, clar_sandbox_path(), "__home"); + + if (!git_fs_path_exists(path.ptr)) + cl_must_pass(p_mkdir(path.ptr, 0777)); + + git_libgit2_opts(GIT_OPT_SET_HOMEDIR, path.ptr); + } + git_str_dispose(&path); } diff --git a/tests/clar/clar_libgit2.h b/tests/clar/clar_libgit2.h index da3f41524..c33b5d28b 100644 --- a/tests/clar/clar_libgit2.h +++ b/tests/clar/clar_libgit2.h @@ -5,6 +5,7 @@ #include #include "common.h" #include "posix.h" +#include "oid.h" /** * Replace for `clar_must_pass` that passes the last library error as the @@ -136,13 +137,32 @@ GIT_INLINE(void) clar__assert_equal_oid( const char *file, const char *func, int line, const char *desc, const git_oid *one, const git_oid *two) { - if (git_oid_cmp(one, two)) { - char err[] = "\"........................................\" != \"........................................\""; + if (git_oid_equal(one, two)) + return; + + if (git_oid_type(one) != git_oid_type(two)) { + char err[64]; + + snprintf(err, 64, "different oid types: %d vs %d", git_oid_type(one), git_oid_type(two)); + clar__fail(file, func, line, desc, err, 1); + } else if (git_oid_type(one) == GIT_OID_SHA1) { + char err[] = "\"........................................\" != \"........................................\""; git_oid_fmt(&err[1], one); git_oid_fmt(&err[47], two); clar__fail(file, func, line, desc, err, 1); +#ifdef GIT_EXPERIMENTAL_SHA256 + } else if (one->type == GIT_OID_SHA256) { + char err[] = "\"................................................................\" != \"................................................................\""; + + git_oid_fmt(&err[1], one); + git_oid_fmt(&err[71], one); + + clar__fail(file, func, line, desc, err, 1); +#endif + } else { + clar__fail(file, func, line, desc, "unknown oid types", 1); } } @@ -211,16 +231,28 @@ void cl_repo_commit_from_index( void cl_repo_set_bool(git_repository *repo, const char *cfg, int value); int cl_repo_get_bool(git_repository *repo, const char *cfg); +void cl_repo_set_int(git_repository *repo, const char *cfg, int value); +int cl_repo_get_int(git_repository *repo, const char *cfg); + void cl_repo_set_string(git_repository *repo, const char *cfg, const char *value); -/* set up a fake "home" directory and set libgit2 GLOBAL search path. - * - * automatically configures cleanup function to restore the regular search - * path, although you can call it explicitly if you wish (with NULL). +/* + * set up a fake "home" directory -- automatically configures cleanup + * function to restore the home directory, although you can call it + * explicitly if you wish (with NULL). */ -void cl_fake_home(void); -void cl_fake_home_cleanup(void *); +void cl_fake_homedir(git_str *); +void cl_fake_homedir_cleanup(void *); +/* + * set up a fake global configuration directory -- automatically + * configures cleanup function to restore the global config + * although you can call it explicitly if you wish (with NULL). + */ +void cl_fake_globalconfig(git_str *); +void cl_fake_globalconfig_cleanup(void *); + +void cl_sandbox_set_homedir(const char *); void cl_sandbox_set_search_path_defaults(void); void cl_sandbox_disable_ownership_validation(void); diff --git a/tests/clar/main.c b/tests/clar/main.c index d879073a8..e3f4fe740 100644 --- a/tests/clar/main.c +++ b/tests/clar/main.c @@ -25,6 +25,7 @@ int main(int argc, char *argv[]) } cl_global_trace_register(); + cl_sandbox_set_homedir(getenv("CLAR_HOMEDIR")); cl_sandbox_set_search_path_defaults(); cl_sandbox_disable_ownership_validation(); diff --git a/tests/libgit2/CMakeLists.txt b/tests/libgit2/CMakeLists.txt index 280b9a8ef..866122d1c 100644 --- a/tests/libgit2/CMakeLists.txt +++ b/tests/libgit2/CMakeLists.txt @@ -65,10 +65,12 @@ endif() include(AddClarTest) add_clar_test(libgit2_tests offline -v -xonline) -add_clar_test(libgit2_tests invasive -v -score::ftruncate -sfilter::stream::bigfile -sodb::largefiles -siterator::workdir::filesystem_gunk -srepo::init -srepo::init::at_filesystem_root) -add_clar_test(libgit2_tests online -v -sonline -xonline::customcert -xonline::clone::ssh_auth_methods) +add_clar_test(libgit2_tests invasive -v -sfilter::stream::bigfile -sodb::largefiles -siterator::workdir::filesystem_gunk -srepo::init -srepo::init::at_filesystem_root) +add_clar_test(libgit2_tests online -v -sonline -xonline::customcert) add_clar_test(libgit2_tests online_customcert -v -sonline::customcert) add_clar_test(libgit2_tests gitdaemon -v -sonline::push) +add_clar_test(libgit2_tests gitdaemon_namespace -v -sonline::clone::namespace) +add_clar_test(libgit2_tests gitdaemon_sha256 -v -sonline::clone::sha256) add_clar_test(libgit2_tests ssh -v -sonline::push -sonline::clone::ssh_cert -sonline::clone::ssh_with_paths -sonline::clone::path_whitespace_ssh -sonline::clone::ssh_auth_methods) add_clar_test(libgit2_tests proxy -v -sonline::clone::proxy) add_clar_test(libgit2_tests auth_clone -v -sonline::clone::cred) diff --git a/tests/libgit2/apply/apply_helpers.c b/tests/libgit2/apply/apply_helpers.c index 91cc51a71..e78b8ffcb 100644 --- a/tests/libgit2/apply/apply_helpers.c +++ b/tests/libgit2/apply/apply_helpers.c @@ -14,7 +14,7 @@ static int iterator_compare(const git_index_entry *entry, void *_data) struct iterator_compare_data *data = (struct iterator_compare_data *)_data; cl_assert_equal_i(GIT_INDEX_ENTRY_STAGE(entry), data->expected[data->idx].stage); - cl_git_pass(git_oid_fromstr(&expected_id, data->expected[data->idx].oid_str)); + cl_git_pass(git_oid__fromstr(&expected_id, data->expected[data->idx].oid_str, GIT_OID_SHA1)); cl_assert_equal_oid(&entry->id, &expected_id); cl_assert_equal_i(entry->mode, data->expected[data->idx].mode); cl_assert_equal_s(entry->path, data->expected[data->idx].path); diff --git a/tests/libgit2/apply/both.c b/tests/libgit2/apply/both.c index 108963270..1331e7ea4 100644 --- a/tests/libgit2/apply/both.c +++ b/tests/libgit2/apply/both.c @@ -12,7 +12,7 @@ void test_apply_both__initialize(void) repo = cl_git_sandbox_init(TEST_REPO_PATH); - git_oid_fromstr(&oid, "539bd011c4822c560c1d17cab095006b7a10f707"); + git_oid__fromstr(&oid, "539bd011c4822c560c1d17cab095006b7a10f707", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &oid)); cl_git_pass(git_reset(repo, (git_object *)commit, GIT_RESET_HARD, NULL)); git_commit_free(commit); @@ -42,8 +42,8 @@ void test_apply_both__generated_diff(void) size_t both_expected_cnt = sizeof(both_expected) / sizeof(struct merge_index_entry); - git_oid_fromstr(&a_oid, "539bd011c4822c560c1d17cab095006b7a10f707"); - git_oid_fromstr(&b_oid, "7c7bf85e978f1d18c0566f702d2cb7766b9c8d4f"); + git_oid__fromstr(&a_oid, "539bd011c4822c560c1d17cab095006b7a10f707", GIT_OID_SHA1); + git_oid__fromstr(&b_oid, "7c7bf85e978f1d18c0566f702d2cb7766b9c8d4f", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&a_commit, repo, &a_oid)); cl_git_pass(git_commit_lookup(&b_commit, repo, &b_oid)); @@ -192,7 +192,7 @@ void test_apply_both__index_must_match_workdir(void) memset(&idx_entry, 0, sizeof(git_index_entry)); idx_entry.mode = 0100644; idx_entry.path = "asparagus.txt"; - cl_git_pass(git_oid_fromstr(&idx_entry.id, "06d3fefb8726ab1099acc76e02dfb85e034b2538")); + cl_git_pass(git_oid__fromstr(&idx_entry.id, "06d3fefb8726ab1099acc76e02dfb85e034b2538", GIT_OID_SHA1)); cl_git_pass(git_index_add(index, &idx_entry)); cl_git_pass(git_index_write(index)); @@ -290,7 +290,7 @@ void test_apply_both__keeps_nonconflicting_changes(void) memset(&idx_entry, 0, sizeof(git_index_entry)); idx_entry.mode = 0100644; idx_entry.path = "beef.txt"; - cl_git_pass(git_oid_fromstr(&idx_entry.id, "898d12687fb35be271c27c795a6b32c8b51da79e")); + cl_git_pass(git_oid__fromstr(&idx_entry.id, "898d12687fb35be271c27c795a6b32c8b51da79e", GIT_OID_SHA1)); cl_git_pass(git_index_add(index, &idx_entry)); cl_git_pass(git_index_remove(index, "bouilli.txt", 0)); @@ -386,7 +386,7 @@ void test_apply_both__honors_crlf_attributes(void) cl_git_rmfile("merge-recursive/asparagus.txt"); cl_git_rmfile("merge-recursive/veal.txt"); - git_oid_fromstr(&oid, "539bd011c4822c560c1d17cab095006b7a10f707"); + git_oid__fromstr(&oid, "539bd011c4822c560c1d17cab095006b7a10f707", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &oid)); cl_git_pass(git_reset(repo, (git_object *)commit, GIT_RESET_HARD, NULL)); git_commit_free(commit); diff --git a/tests/libgit2/apply/callbacks.c b/tests/libgit2/apply/callbacks.c index 1b759dc9b..2f9af3101 100644 --- a/tests/libgit2/apply/callbacks.c +++ b/tests/libgit2/apply/callbacks.c @@ -12,7 +12,7 @@ void test_apply_callbacks__initialize(void) repo = cl_git_sandbox_init(TEST_REPO_PATH); - git_oid_fromstr(&oid, "539bd011c4822c560c1d17cab095006b7a10f707"); + git_oid__fromstr(&oid, "539bd011c4822c560c1d17cab095006b7a10f707", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &oid)); cl_git_pass(git_reset(repo, (git_object *)commit, GIT_RESET_HARD, NULL)); git_commit_free(commit); diff --git a/tests/libgit2/apply/check.c b/tests/libgit2/apply/check.c index 9e42365ed..d055d455b 100644 --- a/tests/libgit2/apply/check.c +++ b/tests/libgit2/apply/check.c @@ -12,7 +12,7 @@ void test_apply_check__initialize(void) repo = cl_git_sandbox_init(TEST_REPO_PATH); - git_oid_fromstr(&oid, "539bd011c4822c560c1d17cab095006b7a10f707"); + git_oid__fromstr(&oid, "539bd011c4822c560c1d17cab095006b7a10f707", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &oid)); cl_git_pass(git_reset(repo, (git_object *)commit, GIT_RESET_HARD, NULL)); git_commit_free(commit); @@ -32,8 +32,8 @@ void test_apply_check__generate_diff(void) git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT; git_apply_options opts = GIT_APPLY_OPTIONS_INIT; - cl_git_pass(git_oid_fromstr(&a_oid, "539bd011c4822c560c1d17cab095006b7a10f707")); - cl_git_pass(git_oid_fromstr(&b_oid, "7c7bf85e978f1d18c0566f702d2cb7766b9c8d4f")); + cl_git_pass(git_oid__fromstr(&a_oid, "539bd011c4822c560c1d17cab095006b7a10f707", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&b_oid, "7c7bf85e978f1d18c0566f702d2cb7766b9c8d4f", GIT_OID_SHA1)); cl_git_pass(git_commit_lookup(&a_commit, repo, &a_oid)); cl_git_pass(git_commit_lookup(&b_commit, repo, &b_oid)); diff --git a/tests/libgit2/apply/index.c b/tests/libgit2/apply/index.c index 9c9094cce..2dc0d53cb 100644 --- a/tests/libgit2/apply/index.c +++ b/tests/libgit2/apply/index.c @@ -12,7 +12,7 @@ void test_apply_index__initialize(void) repo = cl_git_sandbox_init(TEST_REPO_PATH); - git_oid_fromstr(&oid, "539bd011c4822c560c1d17cab095006b7a10f707"); + git_oid__fromstr(&oid, "539bd011c4822c560c1d17cab095006b7a10f707", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &oid)); cl_git_pass(git_reset(repo, (git_object *)commit, GIT_RESET_HARD, NULL)); git_commit_free(commit); @@ -42,8 +42,8 @@ void test_apply_index__generate_diff(void) size_t index_expected_cnt = sizeof(index_expected) / sizeof(struct merge_index_entry); - git_oid_fromstr(&a_oid, "539bd011c4822c560c1d17cab095006b7a10f707"); - git_oid_fromstr(&b_oid, "7c7bf85e978f1d18c0566f702d2cb7766b9c8d4f"); + git_oid__fromstr(&a_oid, "539bd011c4822c560c1d17cab095006b7a10f707", GIT_OID_SHA1); + git_oid__fromstr(&b_oid, "7c7bf85e978f1d18c0566f702d2cb7766b9c8d4f", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&a_commit, repo, &a_oid)); cl_git_pass(git_commit_lookup(&b_commit, repo, &b_oid)); @@ -233,7 +233,7 @@ void test_apply_index__keeps_nonconflicting_changes(void) memset(&idx_entry, 0, sizeof(git_index_entry)); idx_entry.mode = 0100644; idx_entry.path = "beef.txt"; - cl_git_pass(git_oid_fromstr(&idx_entry.id, "898d12687fb35be271c27c795a6b32c8b51da79e")); + cl_git_pass(git_oid__fromstr(&idx_entry.id, "898d12687fb35be271c27c795a6b32c8b51da79e", GIT_OID_SHA1)); cl_git_pass(git_index_add(index, &idx_entry)); cl_git_pass(git_index_remove(index, "bouilli.txt", 0)); @@ -279,7 +279,7 @@ void test_apply_index__can_apply_nonconflicting_file_changes(void) memset(&idx_entry, 0, sizeof(git_index_entry)); idx_entry.mode = 0100644; idx_entry.path = "asparagus.txt"; - cl_git_pass(git_oid_fromstr(&idx_entry.id, "06d3fefb8726ab1099acc76e02dfb85e034b2538")); + cl_git_pass(git_oid__fromstr(&idx_entry.id, "06d3fefb8726ab1099acc76e02dfb85e034b2538", GIT_OID_SHA1)); cl_git_pass(git_index_add(index, &idx_entry)); cl_git_pass(git_index_write(index)); diff --git a/tests/libgit2/apply/tree.c b/tests/libgit2/apply/tree.c index 5154f134f..667bb9d40 100644 --- a/tests/libgit2/apply/tree.c +++ b/tests/libgit2/apply/tree.c @@ -35,8 +35,8 @@ void test_apply_tree__one(void) { 0100644, "a7b066537e6be7109abfe4ff97b675d4e077da20", 0, "veal.txt" }, }; - git_oid_fromstr(&a_oid, "539bd011c4822c560c1d17cab095006b7a10f707"); - git_oid_fromstr(&b_oid, "7c7bf85e978f1d18c0566f702d2cb7766b9c8d4f"); + git_oid__fromstr(&a_oid, "539bd011c4822c560c1d17cab095006b7a10f707", GIT_OID_SHA1); + git_oid__fromstr(&b_oid, "7c7bf85e978f1d18c0566f702d2cb7766b9c8d4f", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&a_commit, repo, &a_oid)); cl_git_pass(git_commit_lookup(&b_commit, repo, &b_oid)); @@ -75,7 +75,7 @@ void test_apply_tree__adds_file(void) { 0100644, "94d2c01087f48213bd157222d54edfefd77c9bba", 0, "veal.txt" }, }; - git_oid_fromstr(&a_oid, "539bd011c4822c560c1d17cab095006b7a10f707"); + git_oid__fromstr(&a_oid, "539bd011c4822c560c1d17cab095006b7a10f707", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&a_commit, repo, &a_oid)); diff --git a/tests/libgit2/apply/workdir.c b/tests/libgit2/apply/workdir.c index d0d9c1aba..e1011d114 100644 --- a/tests/libgit2/apply/workdir.c +++ b/tests/libgit2/apply/workdir.c @@ -12,7 +12,7 @@ void test_apply_workdir__initialize(void) repo = cl_git_sandbox_init(TEST_REPO_PATH); - git_oid_fromstr(&oid, "539bd011c4822c560c1d17cab095006b7a10f707"); + git_oid__fromstr(&oid, "539bd011c4822c560c1d17cab095006b7a10f707", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &oid)); cl_git_pass(git_reset(repo, (git_object *)commit, GIT_RESET_HARD, NULL)); git_commit_free(commit); @@ -42,8 +42,8 @@ void test_apply_workdir__generated_diff(void) size_t workdir_expected_cnt = sizeof(workdir_expected) / sizeof(struct merge_index_entry); - git_oid_fromstr(&a_oid, "539bd011c4822c560c1d17cab095006b7a10f707"); - git_oid_fromstr(&b_oid, "7c7bf85e978f1d18c0566f702d2cb7766b9c8d4f"); cl_git_pass(git_commit_lookup(&a_commit, repo, &a_oid)); + git_oid__fromstr(&a_oid, "539bd011c4822c560c1d17cab095006b7a10f707", GIT_OID_SHA1); + git_oid__fromstr(&b_oid, "7c7bf85e978f1d18c0566f702d2cb7766b9c8d4f", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&a_commit, repo, &a_oid)); cl_git_pass(git_commit_lookup(&b_commit, repo, &b_oid)); cl_git_pass(git_commit_tree(&a_tree, a_commit)); @@ -171,7 +171,7 @@ void test_apply_workdir__modified_index_with_unmodified_workdir_is_ok(void) idx_entry.mode = 0100644; idx_entry.path = "veal.txt"; - cl_git_pass(git_oid_fromstr(&idx_entry.id, "ffb36e513f5fdf8a6ba850a20142676a2ac4807d")); + cl_git_pass(git_oid__fromstr(&idx_entry.id, "ffb36e513f5fdf8a6ba850a20142676a2ac4807d", GIT_OID_SHA1)); cl_git_pass(git_index_add(index, &idx_entry)); cl_git_pass(git_index_remove(index, "asparagus.txt", 0)); diff --git a/tests/libgit2/blame/blame_helpers.c b/tests/libgit2/blame/blame_helpers.c index 6b3ce677d..8aeaa5886 100644 --- a/tests/libgit2/blame/blame_helpers.c +++ b/tests/libgit2/blame/blame_helpers.c @@ -17,7 +17,7 @@ void hunk_message(size_t idx, const git_blame_hunk *hunk, const char *fmt, ...) void check_blame_hunk_index(git_repository *repo, git_blame *blame, int idx, size_t start_line, size_t len, char boundary, const char *commit_id, const char *orig_path) { - char expected[GIT_OID_HEXSZ+1] = {0}, actual[GIT_OID_HEXSZ+1] = {0}; + char expected[GIT_OID_SHA1_HEXSIZE+1] = {0}, actual[GIT_OID_SHA1_HEXSIZE+1] = {0}; const git_blame_hunk *hunk = git_blame_get_hunk_byindex(blame, idx); cl_assert(hunk); diff --git a/tests/libgit2/blame/getters.c b/tests/libgit2/blame/getters.c index 66eaeecf9..c160cd383 100644 --- a/tests/libgit2/blame/getters.c +++ b/tests/libgit2/blame/getters.c @@ -10,11 +10,11 @@ void test_blame_getters__initialize(void) git_blame_options opts = GIT_BLAME_OPTIONS_INIT; git_blame_hunk hunks[] = { - { 3, {{0}}, 1, NULL, {{0}}, "a", 0}, - { 3, {{0}}, 4, NULL, {{0}}, "b", 0}, - { 3, {{0}}, 7, NULL, {{0}}, "c", 0}, - { 3, {{0}}, 10, NULL, {{0}}, "d", 0}, - { 3, {{0}}, 13, NULL, {{0}}, "e", 0}, + { 3, GIT_OID_SHA1_ZERO, 1, NULL, GIT_OID_SHA1_ZERO, "a", 0}, + { 3, GIT_OID_SHA1_ZERO, 4, NULL, GIT_OID_SHA1_ZERO, "b", 0}, + { 3, GIT_OID_SHA1_ZERO, 7, NULL, GIT_OID_SHA1_ZERO, "c", 0}, + { 3, GIT_OID_SHA1_ZERO, 10, NULL, GIT_OID_SHA1_ZERO, "d", 0}, + { 3, GIT_OID_SHA1_ZERO, 13, NULL, GIT_OID_SHA1_ZERO, "e", 0}, }; g_blame = git_blame__alloc(NULL, opts, ""); diff --git a/tests/libgit2/checkout/binaryunicode.c b/tests/libgit2/checkout/binaryunicode.c index edb5cfaf5..b8c6c079e 100644 --- a/tests/libgit2/checkout/binaryunicode.c +++ b/tests/libgit2/checkout/binaryunicode.c @@ -3,6 +3,7 @@ #include "repo/repo_helpers.h" #include "path.h" #include "futils.h" +#include "odb.h" static git_repository *g_repo; @@ -35,13 +36,13 @@ static void execute_test(void) git_commit_free(commit); /* Verify that the lenna.jpg file was checked out correctly */ - cl_git_pass(git_oid_fromstr(&check, "8ab005d890fe53f65eda14b23672f60d9f4ec5a1")); - cl_git_pass(git_odb_hashfile(&oid, "binaryunicode/lenna.jpg", GIT_OBJECT_BLOB)); + cl_git_pass(git_oid__fromstr(&check, "8ab005d890fe53f65eda14b23672f60d9f4ec5a1", GIT_OID_SHA1)); + cl_git_pass(git_odb__hashfile(&oid, "binaryunicode/lenna.jpg", GIT_OBJECT_BLOB, GIT_OID_SHA1)); cl_assert_equal_oid(&oid, &check); /* Verify that the text file was checked out correctly */ - cl_git_pass(git_oid_fromstr(&check, "965b223880dd4249e2c66a0cc0b4cffe1dc40f5a")); - cl_git_pass(git_odb_hashfile(&oid, "binaryunicode/utf16_withbom_noeol_crlf.txt", GIT_OBJECT_BLOB)); + cl_git_pass(git_oid__fromstr(&check, "965b223880dd4249e2c66a0cc0b4cffe1dc40f5a", GIT_OID_SHA1)); + cl_git_pass(git_odb__hashfile(&oid, "binaryunicode/utf16_withbom_noeol_crlf.txt", GIT_OBJECT_BLOB, GIT_OID_SHA1)); cl_assert_equal_oid(&oid, &check); } diff --git a/tests/libgit2/checkout/conflict.c b/tests/libgit2/checkout/conflict.c index 4a9e4b9fa..b2eb939dc 100644 --- a/tests/libgit2/checkout/conflict.c +++ b/tests/libgit2/checkout/conflict.c @@ -49,7 +49,7 @@ static git_index *g_index; struct checkout_index_entry { uint16_t mode; - char oid_str[GIT_OID_HEXSZ+1]; + char oid_str[GIT_OID_SHA1_HEXSIZE+1]; int stage; char path[128]; }; @@ -104,7 +104,7 @@ static void create_index(struct checkout_index_entry *entries, size_t entries_le entry.mode = entries[i].mode; GIT_INDEX_ENTRY_STAGE_SET(&entry, entries[i].stage); - git_oid_fromstr(&entry.id, entries[i].oid_str); + git_oid__fromstr(&entry.id, entries[i].oid_str, GIT_OID_SHA1); entry.path = entries[i].path; cl_git_pass(git_index_add(g_index, &entry)); @@ -155,7 +155,7 @@ static void ensure_workdir_oid(const char *path, const char *oid_str) { git_oid expected, actual; - cl_git_pass(git_oid_fromstr(&expected, oid_str)); + cl_git_pass(git_oid__fromstr(&expected, oid_str, GIT_OID_SHA1)); cl_git_pass(git_repository_hashfile(&actual, g_repo, path, GIT_OBJECT_BLOB, NULL)); cl_assert_equal_oid(&expected, &actual); } diff --git a/tests/libgit2/checkout/index.c b/tests/libgit2/checkout/index.c index 6a80d22c5..6432cba84 100644 --- a/tests/libgit2/checkout/index.c +++ b/tests/libgit2/checkout/index.c @@ -791,15 +791,15 @@ static void add_conflict(git_index *index, const char *path) entry.mode = 0100644; entry.path = path; - git_oid_fromstr(&entry.id, "d427e0b2e138501a3d15cc376077a3631e15bd46"); + git_oid__fromstr(&entry.id, "d427e0b2e138501a3d15cc376077a3631e15bd46", GIT_OID_SHA1); GIT_INDEX_ENTRY_STAGE_SET(&entry, 1); cl_git_pass(git_index_add(index, &entry)); - git_oid_fromstr(&entry.id, "4e886e602529caa9ab11d71f86634bd1b6e0de10"); + git_oid__fromstr(&entry.id, "4e886e602529caa9ab11d71f86634bd1b6e0de10", GIT_OID_SHA1); GIT_INDEX_ENTRY_STAGE_SET(&entry, 2); cl_git_pass(git_index_add(index, &entry)); - git_oid_fromstr(&entry.id, "2bd0a343aeef7a2cf0d158478966a6e587ff3863"); + git_oid__fromstr(&entry.id, "2bd0a343aeef7a2cf0d158478966a6e587ff3863", GIT_OID_SHA1); GIT_INDEX_ENTRY_STAGE_SET(&entry, 3); cl_git_pass(git_index_add(index, &entry)); } diff --git a/tests/libgit2/checkout/tree.c b/tests/libgit2/checkout/tree.c index d4b57f5d1..65df00cd8 100644 --- a/tests/libgit2/checkout/tree.c +++ b/tests/libgit2/checkout/tree.c @@ -139,8 +139,8 @@ void test_checkout_tree__doesnt_write_unrequested_files_to_worktree(void) git_commit* p_chomped_commit; git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; - git_oid_fromstr(&master_oid, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"); - git_oid_fromstr(&chomped_oid, "e90810b8df3e80c413d903f631643c716887138d"); + git_oid__fromstr(&master_oid, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", GIT_OID_SHA1); + git_oid__fromstr(&chomped_oid, "e90810b8df3e80c413d903f631643c716887138d", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&p_master_commit, g_repo, &master_oid)); cl_git_pass(git_commit_lookup(&p_chomped_commit, g_repo, &chomped_oid)); @@ -615,7 +615,7 @@ void test_checkout_tree__donot_update_deleted_file_by_default(void) cl_git_pass(git_repository_index(&index, g_repo)); - cl_git_pass(git_oid_fromstr(&old_id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644")); + cl_git_pass(git_oid__fromstr(&old_id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644", GIT_OID_SHA1)); cl_git_pass(git_commit_lookup(&old_commit, g_repo, &old_id)); cl_git_pass(git_reset(g_repo, (git_object *)old_commit, GIT_RESET_HARD, NULL)); @@ -625,7 +625,7 @@ void test_checkout_tree__donot_update_deleted_file_by_default(void) cl_assert(!git_fs_path_exists("testrepo/branch_file.txt")); - cl_git_pass(git_oid_fromstr(&new_id, "099fabac3a9ea935598528c27f866e34089c2eff")); + cl_git_pass(git_oid__fromstr(&new_id, "099fabac3a9ea935598528c27f866e34089c2eff", GIT_OID_SHA1)); cl_git_pass(git_commit_lookup(&new_commit, g_repo, &new_id)); @@ -941,16 +941,16 @@ static void create_conflict(const char *path) memset(&entry, 0x0, sizeof(git_index_entry)); entry.mode = 0100644; GIT_INDEX_ENTRY_STAGE_SET(&entry, 1); - git_oid_fromstr(&entry.id, "d427e0b2e138501a3d15cc376077a3631e15bd46"); + git_oid__fromstr(&entry.id, "d427e0b2e138501a3d15cc376077a3631e15bd46", GIT_OID_SHA1); entry.path = path; cl_git_pass(git_index_add(index, &entry)); GIT_INDEX_ENTRY_STAGE_SET(&entry, 2); - git_oid_fromstr(&entry.id, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf"); + git_oid__fromstr(&entry.id, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf", GIT_OID_SHA1); cl_git_pass(git_index_add(index, &entry)); GIT_INDEX_ENTRY_STAGE_SET(&entry, 3); - git_oid_fromstr(&entry.id, "2bd0a343aeef7a2cf0d158478966a6e587ff3863"); + git_oid__fromstr(&entry.id, "2bd0a343aeef7a2cf0d158478966a6e587ff3863", GIT_OID_SHA1); cl_git_pass(git_index_add(index, &entry)); cl_git_pass(git_index_write(index)); @@ -988,7 +988,7 @@ void test_checkout_tree__filemode_preserved_in_index(void) cl_git_pass(git_repository_index(&index, g_repo)); /* test a freshly added executable */ - cl_git_pass(git_oid_fromstr(&executable_oid, "afe4393b2b2a965f06acf2ca9658eaa01e0cd6b6")); + cl_git_pass(git_oid__fromstr(&executable_oid, "afe4393b2b2a965f06acf2ca9658eaa01e0cd6b6", GIT_OID_SHA1)); cl_git_pass(git_commit_lookup(&commit, g_repo, &executable_oid)); cl_git_pass(git_checkout_tree(g_repo, (const git_object *)commit, &opts)); @@ -999,7 +999,7 @@ void test_checkout_tree__filemode_preserved_in_index(void) /* Now start with a commit which has a text file */ - cl_git_pass(git_oid_fromstr(&executable_oid, "cf80f8de9f1185bf3a05f993f6121880dd0cfbc9")); + cl_git_pass(git_oid__fromstr(&executable_oid, "cf80f8de9f1185bf3a05f993f6121880dd0cfbc9", GIT_OID_SHA1)); cl_git_pass(git_commit_lookup(&commit, g_repo, &executable_oid)); cl_git_pass(git_checkout_tree(g_repo, (const git_object *)commit, &opts)); @@ -1010,7 +1010,7 @@ void test_checkout_tree__filemode_preserved_in_index(void) /* And then check out to a commit which converts the text file to an executable */ - cl_git_pass(git_oid_fromstr(&executable_oid, "144344043ba4d4a405da03de3844aa829ae8be0e")); + cl_git_pass(git_oid__fromstr(&executable_oid, "144344043ba4d4a405da03de3844aa829ae8be0e", GIT_OID_SHA1)); cl_git_pass(git_commit_lookup(&commit, g_repo, &executable_oid)); cl_git_pass(git_checkout_tree(g_repo, (const git_object *)commit, &opts)); @@ -1021,7 +1021,7 @@ void test_checkout_tree__filemode_preserved_in_index(void) /* Finally, check out the text file again and check that the exec bit is cleared */ - cl_git_pass(git_oid_fromstr(&executable_oid, "cf80f8de9f1185bf3a05f993f6121880dd0cfbc9")); + cl_git_pass(git_oid__fromstr(&executable_oid, "cf80f8de9f1185bf3a05f993f6121880dd0cfbc9", GIT_OID_SHA1)); cl_git_pass(git_commit_lookup(&commit, g_repo, &executable_oid)); cl_git_pass(git_checkout_tree(g_repo, (const git_object *)commit, &opts)); @@ -1063,7 +1063,7 @@ void test_checkout_tree__filemode_preserved_in_workdir(void) opts.checkout_strategy = GIT_CHECKOUT_FORCE; /* test a freshly added executable */ - cl_git_pass(git_oid_fromstr(&executable_oid, "afe4393b2b2a965f06acf2ca9658eaa01e0cd6b6")); + cl_git_pass(git_oid__fromstr(&executable_oid, "afe4393b2b2a965f06acf2ca9658eaa01e0cd6b6", GIT_OID_SHA1)); cl_git_pass(git_commit_lookup(&commit, g_repo, &executable_oid)); cl_git_pass(git_checkout_tree(g_repo, (const git_object *)commit, &opts)); @@ -1073,7 +1073,7 @@ void test_checkout_tree__filemode_preserved_in_workdir(void) /* Now start with a commit which has a text file */ - cl_git_pass(git_oid_fromstr(&executable_oid, "cf80f8de9f1185bf3a05f993f6121880dd0cfbc9")); + cl_git_pass(git_oid__fromstr(&executable_oid, "cf80f8de9f1185bf3a05f993f6121880dd0cfbc9", GIT_OID_SHA1)); cl_git_pass(git_commit_lookup(&commit, g_repo, &executable_oid)); cl_git_pass(git_checkout_tree(g_repo, (const git_object *)commit, &opts)); @@ -1083,7 +1083,7 @@ void test_checkout_tree__filemode_preserved_in_workdir(void) /* And then check out to a commit which converts the text file to an executable */ - cl_git_pass(git_oid_fromstr(&executable_oid, "144344043ba4d4a405da03de3844aa829ae8be0e")); + cl_git_pass(git_oid__fromstr(&executable_oid, "144344043ba4d4a405da03de3844aa829ae8be0e", GIT_OID_SHA1)); cl_git_pass(git_commit_lookup(&commit, g_repo, &executable_oid)); cl_git_pass(git_checkout_tree(g_repo, (const git_object *)commit, &opts)); @@ -1093,7 +1093,7 @@ void test_checkout_tree__filemode_preserved_in_workdir(void) /* Finally, check out the text file again and check that the exec bit is cleared */ - cl_git_pass(git_oid_fromstr(&executable_oid, "cf80f8de9f1185bf3a05f993f6121880dd0cfbc9")); + cl_git_pass(git_oid__fromstr(&executable_oid, "cf80f8de9f1185bf3a05f993f6121880dd0cfbc9", GIT_OID_SHA1)); cl_git_pass(git_commit_lookup(&commit, g_repo, &executable_oid)); cl_git_pass(git_checkout_tree(g_repo, (const git_object *)commit, &opts)); @@ -1112,7 +1112,7 @@ void test_checkout_tree__removes_conflicts(void) git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; git_index *index; - cl_git_pass(git_oid_fromstr(&commit_id, "afe4393b2b2a965f06acf2ca9658eaa01e0cd6b6")); + cl_git_pass(git_oid__fromstr(&commit_id, "afe4393b2b2a965f06acf2ca9658eaa01e0cd6b6", GIT_OID_SHA1)); cl_git_pass(git_commit_lookup(&commit, g_repo, &commit_id)); opts.checkout_strategy = GIT_CHECKOUT_FORCE; @@ -1155,7 +1155,7 @@ void test_checkout_tree__removes_conflicts_only_by_pathscope(void) git_index *index; const char *path = "executable.txt"; - cl_git_pass(git_oid_fromstr(&commit_id, "afe4393b2b2a965f06acf2ca9658eaa01e0cd6b6")); + cl_git_pass(git_oid__fromstr(&commit_id, "afe4393b2b2a965f06acf2ca9658eaa01e0cd6b6", GIT_OID_SHA1)); cl_git_pass(git_commit_lookup(&commit, g_repo, &commit_id)); opts.checkout_strategy = GIT_CHECKOUT_FORCE; @@ -1583,7 +1583,7 @@ static void modify_index_ondisk(void) cl_git_pass(git_repository_open(&other_repo, git_repository_workdir(g_repo))); cl_git_pass(git_repository_index(&other_index, other_repo)); - cl_git_pass(git_oid_fromstr(&entry.id, "1385f264afb75a56a5bec74243be9b367ba4ca08")); + cl_git_pass(git_oid__fromstr(&entry.id, "1385f264afb75a56a5bec74243be9b367ba4ca08", GIT_OID_SHA1)); entry.mode = 0100644; entry.path = "README"; diff --git a/tests/libgit2/checkout/typechange.c b/tests/libgit2/checkout/typechange.c index b888843f0..1fa2d3095 100644 --- a/tests/libgit2/checkout/typechange.c +++ b/tests/libgit2/checkout/typechange.c @@ -319,7 +319,7 @@ void test_checkout_typechange__status_char(void) git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT; char expected[8] = {'M', 'M', 'R', 'T', 'D', 'R', 'A', 'R'}; - git_oid_fromstr(&oid, "9b19edf33a03a0c59cdfc113bfa5c06179bf9b1a"); + git_oid__fromstr(&oid, "9b19edf33a03a0c59cdfc113bfa5c06179bf9b1a", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, g_repo, &oid)); diffopts.flags |= GIT_DIFF_INCLUDE_TYPECHANGE; cl_git_pass(git_diff__commit(&diff, g_repo, commit, &diffopts)); diff --git a/tests/libgit2/cherrypick/bare.c b/tests/libgit2/cherrypick/bare.c index f90ce0226..664468899 100644 --- a/tests/libgit2/cherrypick/bare.c +++ b/tests/libgit2/cherrypick/bare.c @@ -32,10 +32,10 @@ void test_cherrypick_bare__automerge(void) { 0100644, "df6b290e0bd6a89b01d69f66687e8abf385283ca", 0, "file3.txt" }, }; - git_oid_fromstr(&head_oid, "d3d77487660ee3c0194ee01dc5eaf478782b1c7e"); + git_oid__fromstr(&head_oid, "d3d77487660ee3c0194ee01dc5eaf478782b1c7e", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&head, repo, &head_oid)); - git_oid_fromstr(&cherry_oid, "cfc4f0999a8367568e049af4f72e452d40828a15"); + git_oid__fromstr(&cherry_oid, "cfc4f0999a8367568e049af4f72e452d40828a15", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid)); cl_git_pass(git_cherrypick_commit(&index, repo, commit, head, 0, NULL)); @@ -62,10 +62,10 @@ void test_cherrypick_bare__conflicts(void) { 0100644, "e233b9ed408a95e9d4b65fec7fc34943a556deb2", 3, "file3.txt" }, }; - git_oid_fromstr(&head_oid, "bafbf6912c09505ac60575cd43d3f2aba3bd84d8"); + git_oid__fromstr(&head_oid, "bafbf6912c09505ac60575cd43d3f2aba3bd84d8", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&head, repo, &head_oid)); - git_oid_fromstr(&cherry_oid, "e9b63f3655b2ad80c0ff587389b5a9589a3a7110"); + git_oid__fromstr(&cherry_oid, "e9b63f3655b2ad80c0ff587389b5a9589a3a7110", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid)); cl_git_pass(git_cherrypick_commit(&index, repo, commit, head, 0, NULL)); @@ -89,10 +89,10 @@ void test_cherrypick_bare__orphan(void) { 0100644, "9ccb9bf50c011fd58dcbaa65df917bf79539717f", 0, "orphan.txt" }, }; - git_oid_fromstr(&head_oid, "d3d77487660ee3c0194ee01dc5eaf478782b1c7e"); + git_oid__fromstr(&head_oid, "d3d77487660ee3c0194ee01dc5eaf478782b1c7e", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&head, repo, &head_oid)); - git_oid_fromstr(&cherry_oid, "74f06b5bfec6d33d7264f73606b57a7c0b963819"); + git_oid__fromstr(&cherry_oid, "74f06b5bfec6d33d7264f73606b57a7c0b963819", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid)); cl_git_pass(git_cherrypick_commit(&index, repo, commit, head, 0, NULL)); diff --git a/tests/libgit2/cherrypick/workdir.c b/tests/libgit2/cherrypick/workdir.c index 8fd1ecbdf..c16b7814a 100644 --- a/tests/libgit2/cherrypick/workdir.c +++ b/tests/libgit2/cherrypick/workdir.c @@ -57,7 +57,7 @@ void test_cherrypick_workdir__automerge(void) cl_git_pass(git_signature_new(&signature, "Picker", "picker@example.org", time(NULL), 0)); - git_oid_fromstr(&head_oid, "d3d77487660ee3c0194ee01dc5eaf478782b1c7e"); + git_oid__fromstr(&head_oid, "d3d77487660ee3c0194ee01dc5eaf478782b1c7e", GIT_OID_SHA1); for (i = 0; i < 3; ++i) { git_commit *head = NULL, *commit = NULL; @@ -67,7 +67,7 @@ void test_cherrypick_workdir__automerge(void) cl_git_pass(git_commit_lookup(&head, repo, &head_oid)); cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL)); - git_oid_fromstr(&cherry_oid, cherrypick_oids[i]); + git_oid__fromstr(&cherry_oid, cherrypick_oids[i], GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid)); cl_git_pass(git_cherrypick(repo, commit, NULL)); @@ -110,7 +110,7 @@ void test_cherrypick_workdir__empty_result(void) cl_git_pass(git_signature_new(&signature, "Picker", "picker@example.org", time(NULL), 0)); - git_oid_fromstr(&head_oid, "cfc4f0999a8367568e049af4f72e452d40828a15"); + git_oid__fromstr(&head_oid, "cfc4f0999a8367568e049af4f72e452d40828a15", GIT_OID_SHA1); /* Create an untracked file that should not conflict */ cl_git_mkfile(TEST_REPO_PATH "/file4.txt", ""); @@ -119,7 +119,7 @@ void test_cherrypick_workdir__empty_result(void) cl_git_pass(git_commit_lookup(&head, repo, &head_oid)); cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL)); - git_oid_fromstr(&cherry_oid, cherrypick_oid); + git_oid__fromstr(&cherry_oid, cherrypick_oid, GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid)); cl_git_pass(git_cherrypick(repo, commit, NULL)); @@ -151,12 +151,12 @@ void test_cherrypick_workdir__conflicts(void) { 0100644, "e233b9ed408a95e9d4b65fec7fc34943a556deb2", 3, "file3.txt" }, }; - git_oid_fromstr(&head_oid, "bafbf6912c09505ac60575cd43d3f2aba3bd84d8"); + git_oid__fromstr(&head_oid, "bafbf6912c09505ac60575cd43d3f2aba3bd84d8", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&head, repo, &head_oid)); cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL)); - git_oid_fromstr(&cherry_oid, "e9b63f3655b2ad80c0ff587389b5a9589a3a7110"); + git_oid__fromstr(&cherry_oid, "e9b63f3655b2ad80c0ff587389b5a9589a3a7110", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid)); cl_git_pass(git_cherrypick(repo, commit, NULL)); @@ -259,12 +259,12 @@ void test_cherrypick_workdir__conflict_use_ours(void) /* leave the index in a conflicted state, but checkout "ours" to the workdir */ opts.checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_USE_OURS; - git_oid_fromstr(&head_oid, "bafbf6912c09505ac60575cd43d3f2aba3bd84d8"); + git_oid__fromstr(&head_oid, "bafbf6912c09505ac60575cd43d3f2aba3bd84d8", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&head, repo, &head_oid)); cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL)); - git_oid_fromstr(&cherry_oid, "e9b63f3655b2ad80c0ff587389b5a9589a3a7110"); + git_oid__fromstr(&cherry_oid, "e9b63f3655b2ad80c0ff587389b5a9589a3a7110", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid)); cl_git_pass(git_cherrypick(repo, commit, &opts)); @@ -302,11 +302,11 @@ void test_cherrypick_workdir__rename(void) opts.merge_opts.flags |= GIT_MERGE_FIND_RENAMES; opts.merge_opts.rename_threshold = 50; - git_oid_fromstr(&head_oid, "cfc4f0999a8367568e049af4f72e452d40828a15"); + git_oid__fromstr(&head_oid, "cfc4f0999a8367568e049af4f72e452d40828a15", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&head, repo, &head_oid)); cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL)); - git_oid_fromstr(&cherry_oid, "2a26c7e88b285613b302ba76712bc998863f3cbc"); + git_oid__fromstr(&cherry_oid, "2a26c7e88b285613b302ba76712bc998863f3cbc", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid)); cl_git_pass(git_cherrypick(repo, commit, &opts)); @@ -337,11 +337,11 @@ void test_cherrypick_workdir__both_renamed(void) opts.merge_opts.flags |= GIT_MERGE_FIND_RENAMES; opts.merge_opts.rename_threshold = 50; - git_oid_fromstr(&head_oid, "44cd2ed2052c9c68f9a439d208e9614dc2a55c70"); + git_oid__fromstr(&head_oid, "44cd2ed2052c9c68f9a439d208e9614dc2a55c70", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&head, repo, &head_oid)); cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL)); - git_oid_fromstr(&cherry_oid, "2a26c7e88b285613b302ba76712bc998863f3cbc"); + git_oid__fromstr(&cherry_oid, "2a26c7e88b285613b302ba76712bc998863f3cbc", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid)); cl_git_pass(git_cherrypick(repo, commit, &opts)); @@ -388,11 +388,11 @@ void test_cherrypick_workdir__merge_fails_without_mainline_specified(void) git_commit *head, *commit; git_oid head_oid, cherry_oid; - git_oid_fromstr(&head_oid, "cfc4f0999a8367568e049af4f72e452d40828a15"); + git_oid__fromstr(&head_oid, "cfc4f0999a8367568e049af4f72e452d40828a15", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&head, repo, &head_oid)); cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL)); - git_oid_fromstr(&cherry_oid, "abe4603bc7cd5b8167a267e0e2418fd2348f8cff"); + git_oid__fromstr(&cherry_oid, "abe4603bc7cd5b8167a267e0e2418fd2348f8cff", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid)); cl_must_fail(git_cherrypick(repo, commit, NULL)); @@ -420,11 +420,11 @@ void test_cherrypick_workdir__merge_first_parent(void) opts.mainline = 1; - git_oid_fromstr(&head_oid, "cfc4f0999a8367568e049af4f72e452d40828a15"); + git_oid__fromstr(&head_oid, "cfc4f0999a8367568e049af4f72e452d40828a15", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&head, repo, &head_oid)); cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL)); - git_oid_fromstr(&cherry_oid, "abe4603bc7cd5b8167a267e0e2418fd2348f8cff"); + git_oid__fromstr(&cherry_oid, "abe4603bc7cd5b8167a267e0e2418fd2348f8cff", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid)); cl_git_pass(git_cherrypick(repo, commit, &opts)); @@ -452,11 +452,11 @@ void test_cherrypick_workdir__merge_second_parent(void) opts.mainline = 2; - git_oid_fromstr(&head_oid, "cfc4f0999a8367568e049af4f72e452d40828a15"); + git_oid__fromstr(&head_oid, "cfc4f0999a8367568e049af4f72e452d40828a15", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&head, repo, &head_oid)); cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL)); - git_oid_fromstr(&cherry_oid, "abe4603bc7cd5b8167a267e0e2418fd2348f8cff"); + git_oid__fromstr(&cherry_oid, "abe4603bc7cd5b8167a267e0e2418fd2348f8cff", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid)); cl_git_pass(git_cherrypick(repo, commit, &opts)); diff --git a/tests/libgit2/commit/commit.c b/tests/libgit2/commit/commit.c index fd574f7f2..140f87d0c 100644 --- a/tests/libgit2/commit/commit.c +++ b/tests/libgit2/commit/commit.c @@ -26,10 +26,10 @@ void test_commit_commit__create_unexisting_update_ref(void) git_signature *s; git_reference *ref; - git_oid_fromstr(&oid, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"); + git_oid__fromstr(&oid, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, _repo, &oid)); - git_oid_fromstr(&oid, "944c0f6e4dfa41595e6eb3ceecdb14f50fe18162"); + git_oid__fromstr(&oid, "944c0f6e4dfa41595e6eb3ceecdb14f50fe18162", GIT_OID_SHA1); cl_git_pass(git_tree_lookup(&tree, _repo, &oid)); cl_git_pass(git_signature_now(&s, "alice", "alice@example.com")); @@ -59,10 +59,10 @@ void test_commit_commit__create_initial_commit(void) git_signature *s; git_reference *ref; - git_oid_fromstr(&oid, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"); + git_oid__fromstr(&oid, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, _repo, &oid)); - git_oid_fromstr(&oid, "944c0f6e4dfa41595e6eb3ceecdb14f50fe18162"); + git_oid__fromstr(&oid, "944c0f6e4dfa41595e6eb3ceecdb14f50fe18162", GIT_OID_SHA1); cl_git_pass(git_tree_lookup(&tree, _repo, &oid)); cl_git_pass(git_signature_now(&s, "alice", "alice@example.com")); @@ -89,10 +89,10 @@ void test_commit_commit__create_initial_commit_parent_not_current(void) git_commit *commit; git_signature *s; - git_oid_fromstr(&oid, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"); + git_oid__fromstr(&oid, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, _repo, &oid)); - git_oid_fromstr(&oid, "944c0f6e4dfa41595e6eb3ceecdb14f50fe18162"); + git_oid__fromstr(&oid, "944c0f6e4dfa41595e6eb3ceecdb14f50fe18162", GIT_OID_SHA1); cl_git_pass(git_tree_lookup(&tree, _repo, &oid)); cl_git_pass(git_signature_now(&s, "alice", "alice@example.com")); diff --git a/tests/libgit2/commit/parent.c b/tests/libgit2/commit/parent.c index 18ce0bba6..1ec96babb 100644 --- a/tests/libgit2/commit/parent.c +++ b/tests/libgit2/commit/parent.c @@ -9,7 +9,7 @@ void test_commit_parent__initialize(void) cl_git_pass(git_repository_open(&_repo, cl_fixture("testrepo.git"))); - git_oid_fromstr(&oid, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"); + git_oid__fromstr(&oid, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, _repo, &oid)); } diff --git a/tests/libgit2/commit/parse.c b/tests/libgit2/commit/parse.c index 04366d7d2..3a1fc3d26 100644 --- a/tests/libgit2/commit/parse.c +++ b/tests/libgit2/commit/parse.c @@ -56,7 +56,8 @@ void test_commit_parse__header(void) const char *line = testcase->line; const char *line_end = line + strlen(line); - cl_git_pass(git_oid__parse(&oid, &line, line_end, testcase->header)); + cl_git_pass(git_object__parse_oid_header(&oid, + &line, line_end, testcase->header, GIT_OID_SHA1)); cl_assert(line == line_end); } @@ -65,7 +66,8 @@ void test_commit_parse__header(void) const char *line = testcase->line; const char *line_end = line + strlen(line); - cl_git_fail(git_oid__parse(&oid, &line, line_end, testcase->header)); + cl_git_fail(git_object__parse_oid_header(&oid, + &line, line_end, testcase->header, GIT_OID_SHA1)); } } @@ -285,7 +287,7 @@ static int parse_commit(git_commit **out, const char *buffer) fake_odb_object.buffer = (char *)buffer; fake_odb_object.cached.size = strlen(fake_odb_object.buffer); - error = git_commit__parse(commit, &fake_odb_object); + error = git_commit__parse(commit, &fake_odb_object, GIT_OID_SHA1); *out = commit; return error; @@ -341,7 +343,7 @@ void test_commit_parse__details0(void) { unsigned int parents, p; git_commit *parent = NULL, *old_parent = NULL; - git_oid_fromstr(&id, commit_ids[i]); + git_oid__fromstr(&id, commit_ids[i], GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, g_repo, &id)); @@ -531,7 +533,7 @@ corrupt signature\n"; git_buf_dispose(&signed_data); /* Try to parse a tree */ - cl_git_pass(git_oid_fromstr(&commit_id, "45dd856fdd4d89b884c340ba0e047752d9b085d6")); + cl_git_pass(git_oid__fromstr(&commit_id, "45dd856fdd4d89b884c340ba0e047752d9b085d6", GIT_OID_SHA1)); cl_git_fail_with(GIT_ENOTFOUND, git_commit_extract_signature(&signature, &signed_data, g_repo, &commit_id, NULL)); cl_assert_equal_i(GIT_ERROR_INVALID, git_error_last()->klass); diff --git a/tests/libgit2/commit/write.c b/tests/libgit2/commit/write.c index 5a9c9d5a5..890f7384b 100644 --- a/tests/libgit2/commit/write.c +++ b/tests/libgit2/commit/write.c @@ -51,10 +51,10 @@ void test_commit_write__from_memory(void) git_commit *parent; git_tree *tree; - git_oid_fromstr(&tree_id, tree_id_str); + git_oid__fromstr(&tree_id, tree_id_str, GIT_OID_SHA1); cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_id)); - git_oid_fromstr(&parent_id, parent_id_str); + git_oid__fromstr(&parent_id, parent_id_str, GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&parent, g_repo, &parent_id)); /* create signatures */ @@ -107,14 +107,14 @@ void test_commit_write__into_buf(void) git_oid parent_id; git_buf commit = GIT_BUF_INIT; - git_oid_fromstr(&tree_id, tree_id_str); + git_oid__fromstr(&tree_id, tree_id_str, GIT_OID_SHA1); cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_id)); /* create signatures */ cl_git_pass(git_signature_new(&committer, committer_name, committer_email, 123456789, 60)); cl_git_pass(git_signature_new(&author, committer_name, committer_email, 987654321, 90)); - git_oid_fromstr(&parent_id, parent_id_str); + git_oid__fromstr(&parent_id, parent_id_str, GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&parent, g_repo, &parent_id)); cl_git_pass(git_commit_create_buffer(&commit, g_repo, author, committer, @@ -148,7 +148,7 @@ void test_commit_write__root(void) git_reflog *log; const git_reflog_entry *entry; - git_oid_fromstr(&tree_id, tree_id_str); + git_oid__fromstr(&tree_id, tree_id_str, GIT_OID_SHA1); cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_id)); /* create signatures */ @@ -242,34 +242,34 @@ void test_commit_write__can_write_invalid_objects(void) cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_STRICT_OBJECT_CREATION, 0)); /* this is a valid tree and parent */ - git_oid_fromstr(&tree_id, tree_id_str); - git_oid_fromstr(&parent_id, parent_id_str); + git_oid__fromstr(&tree_id, tree_id_str, GIT_OID_SHA1); + git_oid__fromstr(&parent_id, parent_id_str, GIT_OID_SHA1); - git_oid_fromstr(&expected_id, "c8571bbec3a72c4bcad31648902e5a453f1adece"); + git_oid__fromstr(&expected_id, "c8571bbec3a72c4bcad31648902e5a453f1adece", GIT_OID_SHA1); cl_git_pass(create_commit_from_ids(&commit_id, &tree_id, &parent_id)); cl_assert_equal_oid(&expected_id, &commit_id); /* this is a wholly invented tree id */ - git_oid_fromstr(&tree_id, "1234567890123456789012345678901234567890"); - git_oid_fromstr(&parent_id, parent_id_str); + git_oid__fromstr(&tree_id, "1234567890123456789012345678901234567890", GIT_OID_SHA1); + git_oid__fromstr(&parent_id, parent_id_str, GIT_OID_SHA1); - git_oid_fromstr(&expected_id, "996008340b8e68d69bf3c28d7c57fb7ec3c8e202"); + git_oid__fromstr(&expected_id, "996008340b8e68d69bf3c28d7c57fb7ec3c8e202", GIT_OID_SHA1); cl_git_pass(create_commit_from_ids(&commit_id, &tree_id, &parent_id)); cl_assert_equal_oid(&expected_id, &commit_id); /* this is a wholly invented parent id */ - git_oid_fromstr(&tree_id, tree_id_str); - git_oid_fromstr(&parent_id, "1234567890123456789012345678901234567890"); + git_oid__fromstr(&tree_id, tree_id_str, GIT_OID_SHA1); + git_oid__fromstr(&parent_id, "1234567890123456789012345678901234567890", GIT_OID_SHA1); - git_oid_fromstr(&expected_id, "d78f660cab89d9791ca6714b57978bf2a7e709fd"); + git_oid__fromstr(&expected_id, "d78f660cab89d9791ca6714b57978bf2a7e709fd", GIT_OID_SHA1); cl_git_pass(create_commit_from_ids(&commit_id, &tree_id, &parent_id)); cl_assert_equal_oid(&expected_id, &commit_id); /* these are legitimate objects, but of the wrong type */ - git_oid_fromstr(&tree_id, parent_id_str); - git_oid_fromstr(&parent_id, tree_id_str); + git_oid__fromstr(&tree_id, parent_id_str, GIT_OID_SHA1); + git_oid__fromstr(&parent_id, tree_id_str, GIT_OID_SHA1); - git_oid_fromstr(&expected_id, "5d80c07414e3f18792949699dfcacadf7748f361"); + git_oid__fromstr(&expected_id, "5d80c07414e3f18792949699dfcacadf7748f361", GIT_OID_SHA1); cl_git_pass(create_commit_from_ids(&commit_id, &tree_id, &parent_id)); cl_assert_equal_oid(&expected_id, &commit_id); } @@ -279,23 +279,23 @@ void test_commit_write__can_validate_objects(void) git_oid tree_id, parent_id, commit_id; /* this is a valid tree and parent */ - git_oid_fromstr(&tree_id, tree_id_str); - git_oid_fromstr(&parent_id, parent_id_str); + git_oid__fromstr(&tree_id, tree_id_str, GIT_OID_SHA1); + git_oid__fromstr(&parent_id, parent_id_str, GIT_OID_SHA1); cl_git_pass(create_commit_from_ids(&commit_id, &tree_id, &parent_id)); /* this is a wholly invented tree id */ - git_oid_fromstr(&tree_id, "1234567890123456789012345678901234567890"); - git_oid_fromstr(&parent_id, parent_id_str); + git_oid__fromstr(&tree_id, "1234567890123456789012345678901234567890", GIT_OID_SHA1); + git_oid__fromstr(&parent_id, parent_id_str, GIT_OID_SHA1); cl_git_fail(create_commit_from_ids(&commit_id, &tree_id, &parent_id)); /* this is a wholly invented parent id */ - git_oid_fromstr(&tree_id, tree_id_str); - git_oid_fromstr(&parent_id, "1234567890123456789012345678901234567890"); + git_oid__fromstr(&tree_id, tree_id_str, GIT_OID_SHA1); + git_oid__fromstr(&parent_id, "1234567890123456789012345678901234567890", GIT_OID_SHA1); cl_git_fail(create_commit_from_ids(&commit_id, &tree_id, &parent_id)); /* these are legitimate objects, but of the wrong type */ - git_oid_fromstr(&tree_id, parent_id_str); - git_oid_fromstr(&parent_id, tree_id_str); + git_oid__fromstr(&tree_id, parent_id_str, GIT_OID_SHA1); + git_oid__fromstr(&parent_id, tree_id_str, GIT_OID_SHA1); cl_git_fail(create_commit_from_ids(&commit_id, &tree_id, &parent_id)); } diff --git a/tests/libgit2/config/find.c b/tests/libgit2/config/find.c new file mode 100644 index 000000000..7ca8ec767 --- /dev/null +++ b/tests/libgit2/config/find.c @@ -0,0 +1,11 @@ +#include "clar_libgit2.h" + +void test_config_find__one(void) +{ + git_buf buf = GIT_BUF_INIT; + + cl_git_fail_with(GIT_ENOTFOUND, git_config_find_global(&buf)); + cl_git_fail_with(GIT_ENOTFOUND, git_config_find_xdg(&buf)); + cl_git_fail_with(GIT_ENOTFOUND, git_config_find_system(&buf)); + cl_git_fail_with(GIT_ENOTFOUND, git_config_find_programdata(&buf)); +} diff --git a/tests/libgit2/config/include.c b/tests/libgit2/config/include.c index 9328f3cf6..1b55fdc86 100644 --- a/tests/libgit2/config/include.c +++ b/tests/libgit2/config/include.c @@ -42,8 +42,13 @@ void test_config_include__absolute(void) void test_config_include__homedir(void) { - cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, cl_fixture("config"))); + git_str homefile = GIT_STR_INIT; + + cl_fake_homedir(&homefile); + cl_git_pass(git_str_joinpath(&homefile, homefile.ptr, "config-included")); + cl_git_mkfile("config-include-homedir", "[include]\npath = ~/config-included"); + cl_git_mkfile(homefile.ptr, "[foo \"bar\"]\n\tbaz = huzzah\n"); cl_git_pass(git_config_open_ondisk(&cfg, "config-include-homedir")); @@ -53,6 +58,8 @@ void test_config_include__homedir(void) cl_sandbox_set_search_path_defaults(); cl_git_pass(p_unlink("config-include-homedir")); + + git_str_dispose(&homefile); } /* We need to pretend that the variables were defined where the file was included */ @@ -113,7 +120,8 @@ void test_config_include__missing(void) void test_config_include__missing_homedir(void) { - cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, cl_fixture("config"))); + cl_fake_homedir(NULL); + cl_git_mkfile("including", "[include]\npath = ~/.nonexistentfile\n[foo]\nbar = baz"); git_error_clear(); diff --git a/tests/libgit2/config/read.c b/tests/libgit2/config/read.c index a2e668c20..ac6459b9e 100644 --- a/tests/libgit2/config/read.c +++ b/tests/libgit2/config/read.c @@ -728,14 +728,11 @@ void test_config_read__path(void) { git_config *cfg; git_buf path = GIT_BUF_INIT; - git_buf old_path = GIT_BUF_INIT; git_str home_path = GIT_STR_INIT; git_str expected_path = GIT_STR_INIT; - cl_git_pass(p_mkdir("fakehome", 0777)); - cl_git_pass(git_fs_path_prettify(&home_path, "fakehome", NULL)); - cl_git_pass(git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, &old_path)); - cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, home_path.ptr)); + cl_fake_homedir(&home_path); + cl_git_mkfile("./testconfig", "[some]\n path = ~/somefile"); cl_git_pass(git_fs_path_join_unrooted(&expected_path, "somefile", home_path.ptr, NULL)); @@ -761,8 +758,6 @@ void test_config_read__path(void) cl_git_mkfile("./testconfig", "[some]\n path = ~user/foo"); cl_git_fail(git_config_get_path(&path, cfg, "some.path")); - cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, old_path.ptr)); - git_buf_dispose(&old_path); git_str_dispose(&home_path); git_str_dispose(&expected_path); git_config_free(cfg); diff --git a/tests/libgit2/core/oid.c b/tests/libgit2/core/oid.c index 894feadf6..a405b3344 100644 --- a/tests/libgit2/core/oid.c +++ b/tests/libgit2/core/oid.c @@ -1,79 +1,213 @@ #include "clar_libgit2.h" #include "oid.h" -static git_oid id; -static git_oid idp; -static git_oid idm; -const char *str_oid = "ae90f12eea699729ed24555e40b9fd669da12a12"; -const char *str_oid_p = "ae90f12eea699729ed"; -const char *str_oid_m = "ae90f12eea699729ed24555e40b9fd669da12a12THIS IS EXTRA TEXT THAT SHOULD GET IGNORED"; +static git_oid id_sha1; +static git_oid idp_sha1; +static git_oid idm_sha1; + +const char *str_oid_sha1 = "ae90f12eea699729ed24555e40b9fd669da12a12"; +const char *str_oid_sha1_p = "ae90f12eea699729ed"; +const char *str_oid_sha1_m = "ae90f12eea699729ed24555e40b9fd669da12a12THIS IS EXTRA TEXT THAT SHOULD GET IGNORED"; + +#ifdef GIT_EXPERIMENTAL_SHA256 +static git_oid id_sha256; +static git_oid idp_sha256; +static git_oid idm_sha256; + +const char *str_oid_sha256 = "d3e63d2f2e43d1fee23a74bf19a0ede156cba2d1bd602eba13de433cea1bb512"; +const char *str_oid_sha256_p = "d3e63d2f2e43d1fee2"; +const char *str_oid_sha256_m = "d3e63d2f2e43d1fee23a74bf19a0ede156cba2d1bd602eba13de433cea1bb512 GARBAGE EXTRA TEXT AT THE END"; +#endif void test_core_oid__initialize(void) { - cl_git_pass(git_oid_fromstr(&id, str_oid)); - cl_git_pass(git_oid_fromstrp(&idp, str_oid_p)); - cl_git_fail(git_oid_fromstrp(&idm, str_oid_m)); + cl_git_pass(git_oid__fromstr(&id_sha1, str_oid_sha1, GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstrp(&idp_sha1, str_oid_sha1_p, GIT_OID_SHA1)); + cl_git_fail(git_oid__fromstrp(&idm_sha1, str_oid_sha1_m, GIT_OID_SHA1)); + +#ifdef GIT_EXPERIMENTAL_SHA256 + cl_git_pass(git_oid__fromstr(&id_sha256, str_oid_sha256, GIT_OID_SHA256)); + cl_git_pass(git_oid__fromstrp(&idp_sha256, str_oid_sha256_p, GIT_OID_SHA256)); + cl_git_fail(git_oid__fromstrp(&idm_sha256, str_oid_sha256_m, GIT_OID_SHA256)); +#endif } -void test_core_oid__streq(void) +void test_core_oid__streq_sha1(void) { - cl_assert_equal_i(0, git_oid_streq(&id, str_oid)); - cl_assert_equal_i(-1, git_oid_streq(&id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef")); + cl_assert_equal_i(0, git_oid_streq(&id_sha1, str_oid_sha1)); + cl_assert_equal_i(-1, git_oid_streq(&id_sha1, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef")); - cl_assert_equal_i(-1, git_oid_streq(&id, "deadbeef")); - cl_assert_equal_i(-1, git_oid_streq(&id, "I'm not an oid.... :)")); + cl_assert_equal_i(-1, git_oid_streq(&id_sha1, "deadbeef")); + cl_assert_equal_i(-1, git_oid_streq(&id_sha1, "I'm not an oid.... :)")); - cl_assert_equal_i(0, git_oid_streq(&idp, "ae90f12eea699729ed0000000000000000000000")); - cl_assert_equal_i(0, git_oid_streq(&idp, "ae90f12eea699729ed")); - cl_assert_equal_i(-1, git_oid_streq(&idp, "ae90f12eea699729ed1")); - cl_assert_equal_i(-1, git_oid_streq(&idp, "ae90f12eea699729ec")); - cl_assert_equal_i(-1, git_oid_streq(&idp, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef")); + cl_assert_equal_i(0, git_oid_streq(&idp_sha1, "ae90f12eea699729ed0000000000000000000000")); + cl_assert_equal_i(0, git_oid_streq(&idp_sha1, "ae90f12eea699729ed")); + cl_assert_equal_i(-1, git_oid_streq(&idp_sha1, "ae90f12eea699729ed1")); + cl_assert_equal_i(-1, git_oid_streq(&idp_sha1, "ae90f12eea699729ec")); + cl_assert_equal_i(-1, git_oid_streq(&idp_sha1, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef")); - cl_assert_equal_i(-1, git_oid_streq(&idp, "deadbeef")); - cl_assert_equal_i(-1, git_oid_streq(&idp, "I'm not an oid.... :)")); + cl_assert_equal_i(-1, git_oid_streq(&idp_sha1, "deadbeef")); + cl_assert_equal_i(-1, git_oid_streq(&idp_sha1, "I'm not an oid.... :)")); } -void test_core_oid__strcmp(void) +void test_core_oid__streq_sha256(void) { - cl_assert_equal_i(0, git_oid_strcmp(&id, str_oid)); - cl_assert(git_oid_strcmp(&id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef") < 0); +#ifndef GIT_EXPERIMENTAL_SHA256 + cl_skip(); +#else + cl_assert_equal_i(0, git_oid_streq(&id_sha256, str_oid_sha256)); + cl_assert_equal_i(-1, git_oid_streq(&id_sha256, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef")); - cl_assert(git_oid_strcmp(&id, "deadbeef") < 0); - cl_assert_equal_i(-1, git_oid_strcmp(&id, "I'm not an oid.... :)")); + cl_assert_equal_i(-1, git_oid_streq(&id_sha256, "deadbeef")); + cl_assert_equal_i(-1, git_oid_streq(&id_sha256, "I'm not an oid.... :)")); - cl_assert_equal_i(0, git_oid_strcmp(&idp, "ae90f12eea699729ed0000000000000000000000")); - cl_assert_equal_i(0, git_oid_strcmp(&idp, "ae90f12eea699729ed")); - cl_assert(git_oid_strcmp(&idp, "ae90f12eea699729ed1") < 0); - cl_assert(git_oid_strcmp(&idp, "ae90f12eea699729ec") > 0); - cl_assert(git_oid_strcmp(&idp, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef") < 0); + cl_assert_equal_i(0, git_oid_streq(&idp_sha256, "d3e63d2f2e43d1fee20000000000000000000000000000000000000000000000")); + cl_assert_equal_i(0, git_oid_streq(&idp_sha256, "d3e63d2f2e43d1fee2")); + cl_assert_equal_i(-1, git_oid_streq(&idp_sha1, "d3e63d2f2e43d1fee21")); + cl_assert_equal_i(-1, git_oid_streq(&idp_sha1, "d3e63d2f2e43d1fee1")); + cl_assert_equal_i(-1, git_oid_streq(&idp_sha256, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef")); - cl_assert(git_oid_strcmp(&idp, "deadbeef") < 0); - cl_assert_equal_i(-1, git_oid_strcmp(&idp, "I'm not an oid.... :)")); + cl_assert_equal_i(-1, git_oid_streq(&idp_sha1, "deadbeef")); + cl_assert_equal_i(-1, git_oid_streq(&idp_sha1, "I'm not an oid.... :)")); +#endif } -void test_core_oid__ncmp(void) +void test_core_oid__strcmp_sha1(void) { - cl_assert(!git_oid_ncmp(&id, &idp, 0)); - cl_assert(!git_oid_ncmp(&id, &idp, 1)); - cl_assert(!git_oid_ncmp(&id, &idp, 2)); - cl_assert(!git_oid_ncmp(&id, &idp, 17)); - cl_assert(!git_oid_ncmp(&id, &idp, 18)); - cl_assert(git_oid_ncmp(&id, &idp, 19)); - cl_assert(git_oid_ncmp(&id, &idp, 40)); - cl_assert(git_oid_ncmp(&id, &idp, 41)); - cl_assert(git_oid_ncmp(&id, &idp, 42)); + cl_assert_equal_i(0, git_oid_strcmp(&id_sha1, str_oid_sha1)); + cl_assert(git_oid_strcmp(&id_sha1, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef") < 0); - cl_assert(!git_oid_ncmp(&id, &id, 0)); - cl_assert(!git_oid_ncmp(&id, &id, 1)); - cl_assert(!git_oid_ncmp(&id, &id, 39)); - cl_assert(!git_oid_ncmp(&id, &id, 40)); - cl_assert(!git_oid_ncmp(&id, &id, 41)); + cl_assert(git_oid_strcmp(&id_sha1, "deadbeef") < 0); + cl_assert_equal_i(-1, git_oid_strcmp(&id_sha1, "I'm not an oid.... :)")); + + cl_assert_equal_i(0, git_oid_strcmp(&idp_sha1, "ae90f12eea699729ed0000000000000000000000")); + cl_assert_equal_i(0, git_oid_strcmp(&idp_sha1, "ae90f12eea699729ed")); + cl_assert(git_oid_strcmp(&idp_sha1, "ae90f12eea699729ed1") < 0); + cl_assert(git_oid_strcmp(&idp_sha1, "ae90f12eea699729ec") > 0); + cl_assert(git_oid_strcmp(&idp_sha1, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef") < 0); + + cl_assert(git_oid_strcmp(&idp_sha1, "deadbeef") < 0); + cl_assert_equal_i(-1, git_oid_strcmp(&idp_sha1, "I'm not an oid.... :)")); +} + +void test_core_oid__strcmp_sha256(void) +{ +#ifndef GIT_EXPERIMENTAL_SHA256 + cl_skip(); +#else + cl_assert_equal_i(0, git_oid_strcmp(&id_sha256, str_oid_sha256)); + cl_assert(git_oid_strcmp(&id_sha256, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef") < 0); + + cl_assert(git_oid_strcmp(&id_sha256, "deadbeef") < 0); + cl_assert_equal_i(-1, git_oid_strcmp(&id_sha256, "I'm not an oid.... :)")); + + cl_assert_equal_i(0, git_oid_strcmp(&idp_sha256, "d3e63d2f2e43d1fee20000000000000000000000")); + cl_assert_equal_i(0, git_oid_strcmp(&idp_sha256, "d3e63d2f2e43d1fee2")); + cl_assert(git_oid_strcmp(&idp_sha256, "d3e63d2f2e43d1fee21") < 0); + cl_assert(git_oid_strcmp(&idp_sha256, "d3e63d2f2e43d1fee1") > 0); + cl_assert(git_oid_strcmp(&idp_sha256, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef") < 0); + + cl_assert(git_oid_strcmp(&idp_sha256, "deadbeef") < 0); + cl_assert_equal_i(-1, git_oid_strcmp(&idp_sha256, "I'm not an oid.... :)")); +#endif +} + +void test_core_oid__ncmp_sha1(void) +{ + cl_assert(!git_oid_ncmp(&id_sha1, &idp_sha1, 0)); + cl_assert(!git_oid_ncmp(&id_sha1, &idp_sha1, 1)); + cl_assert(!git_oid_ncmp(&id_sha1, &idp_sha1, 2)); + cl_assert(!git_oid_ncmp(&id_sha1, &idp_sha1, 17)); + cl_assert(!git_oid_ncmp(&id_sha1, &idp_sha1, 18)); + cl_assert(git_oid_ncmp(&id_sha1, &idp_sha1, 19)); + cl_assert(git_oid_ncmp(&id_sha1, &idp_sha1, 40)); + cl_assert(git_oid_ncmp(&id_sha1, &idp_sha1, 41)); + cl_assert(git_oid_ncmp(&id_sha1, &idp_sha1, 42)); + + cl_assert(!git_oid_ncmp(&id_sha1, &id_sha1, 0)); + cl_assert(!git_oid_ncmp(&id_sha1, &id_sha1, 1)); + cl_assert(!git_oid_ncmp(&id_sha1, &id_sha1, 39)); + cl_assert(!git_oid_ncmp(&id_sha1, &id_sha1, 40)); + cl_assert(!git_oid_ncmp(&id_sha1, &id_sha1, 41)); +} + +void test_core_oid__ncmp_sha256(void) +{ +#ifndef GIT_EXPERIMENTAL_SHA256 + cl_skip(); +#else + cl_assert(!git_oid_ncmp(&id_sha256, &idp_sha256, 0)); + cl_assert(!git_oid_ncmp(&id_sha256, &idp_sha256, 1)); + cl_assert(!git_oid_ncmp(&id_sha256, &idp_sha256, 2)); + cl_assert(!git_oid_ncmp(&id_sha256, &idp_sha256, 17)); + cl_assert(!git_oid_ncmp(&id_sha256, &idp_sha256, 18)); + cl_assert(git_oid_ncmp(&id_sha256, &idp_sha256, 19)); + cl_assert(git_oid_ncmp(&id_sha256, &idp_sha256, 40)); + cl_assert(git_oid_ncmp(&id_sha256, &idp_sha256, 41)); + cl_assert(git_oid_ncmp(&id_sha256, &idp_sha256, 42)); + cl_assert(git_oid_ncmp(&id_sha256, &idp_sha256, 63)); + cl_assert(git_oid_ncmp(&id_sha256, &idp_sha256, 64)); + cl_assert(git_oid_ncmp(&id_sha256, &idp_sha256, 65)); + + cl_assert(!git_oid_ncmp(&id_sha256, &id_sha256, 0)); + cl_assert(!git_oid_ncmp(&id_sha256, &id_sha256, 1)); + cl_assert(!git_oid_ncmp(&id_sha256, &id_sha256, 39)); + cl_assert(!git_oid_ncmp(&id_sha256, &id_sha256, 40)); + cl_assert(!git_oid_ncmp(&id_sha256, &id_sha256, 41)); + cl_assert(!git_oid_ncmp(&id_sha256, &id_sha256, 63)); + cl_assert(!git_oid_ncmp(&id_sha256, &id_sha256, 64)); + cl_assert(!git_oid_ncmp(&id_sha256, &id_sha256, 65)); +#endif } void test_core_oid__is_hexstr(void) { - cl_assert(git_oid__is_hexstr("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef")); - cl_assert(!git_oid__is_hexstr("deadbeefdeadbeef")); - cl_assert(!git_oid__is_hexstr("zeadbeefdeadbeefdeadbeefdeadbeefdeadbeef")); - cl_assert(!git_oid__is_hexstr("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef1")); + cl_assert(git_oid__is_hexstr("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef", GIT_OID_SHA1)); + cl_assert(!git_oid__is_hexstr("deadbeefdeadbeef", GIT_OID_SHA1)); + cl_assert(!git_oid__is_hexstr("zeadbeefdeadbeefdeadbeefdeadbeefdeadbeef", GIT_OID_SHA1)); + cl_assert(!git_oid__is_hexstr("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef1", GIT_OID_SHA1)); +} + +void test_core_oid__fmt_substr_sha1(void) +{ + char buf[GIT_OID_MAX_HEXSIZE + 1]; + + memset(buf, 0, GIT_OID_MAX_HEXSIZE + 1); + git_oid_fmt_substr(buf, &id_sha1, 0, 40); + cl_assert_equal_s(buf, str_oid_sha1); + + memset(buf, 0, GIT_OID_MAX_HEXSIZE + 1); + git_oid_fmt_substr(buf, &id_sha1, 0, 18); + cl_assert_equal_s(buf, str_oid_sha1_p); + + memset(buf, 0, GIT_OID_MAX_HEXSIZE + 1); + git_oid_fmt_substr(buf, &id_sha1, 0, 5); + cl_assert_equal_s(buf, "ae90f"); + + memset(buf, 0, GIT_OID_MAX_HEXSIZE + 1); + git_oid_fmt_substr(buf, &id_sha1, 5, 5); + cl_assert_equal_s(buf, "12eea"); + + memset(buf, 0, GIT_OID_MAX_HEXSIZE + 1); + git_oid_fmt_substr(buf, &id_sha1, 5, 6); + cl_assert_equal_s(buf, "12eea6"); +} + +void test_core_oid__type_lookup(void) +{ + cl_assert_equal_i(GIT_OID_SHA1, git_oid_type_fromstr("sha1")); + cl_assert_equal_i(GIT_OID_SHA1, git_oid_type_fromstrn("sha1...", 4)); + cl_assert_equal_s("sha1", git_oid_type_name(GIT_OID_SHA1)); + +#ifdef GIT_EXPERIMENTAL_SHA256 + cl_assert_equal_i(GIT_OID_SHA256, git_oid_type_fromstr("sha256")); + cl_assert_equal_i(GIT_OID_SHA256, git_oid_type_fromstrn("sha256...", 6)); + cl_assert_equal_s("sha256", git_oid_type_name(GIT_OID_SHA256)); +#endif + + cl_assert_equal_i(0, git_oid_type_fromstr("sha42")); + cl_assert_equal_i(0, git_oid_type_fromstrn("sha1", 3)); + cl_assert_equal_i(0, git_oid_type_fromstrn("sha1...", 5)); + cl_assert_equal_s("unknown", git_oid_type_name(0)); + cl_assert_equal_s("unknown", git_oid_type_name(42)); } diff --git a/tests/libgit2/core/oidmap.c b/tests/libgit2/core/oidmap.c index 7f98287a6..34374ceef 100644 --- a/tests/libgit2/core/oidmap.c +++ b/tests/libgit2/core/oidmap.c @@ -17,7 +17,7 @@ void test_core_oidmap__initialize(void) test_oids[i].extra = i; - for (j = 0; j < GIT_OID_RAWSZ / 4; ++j) { + for (j = 0; j < GIT_OID_SHA1_SIZE / 4; ++j) { test_oids[i].oid.id[j * 4 ] = (unsigned char)modi; test_oids[i].oid.id[j * 4 + 1] = (unsigned char)(modi >> 8); test_oids[i].oid.id[j * 4 + 2] = (unsigned char)(modi >> 16); @@ -28,6 +28,9 @@ void test_core_oidmap__initialize(void) test_oids[i].oid.id[ 9] = (unsigned char)(i >> 8); test_oids[i].oid.id[10] = (unsigned char)(i >> 16); test_oids[i].oid.id[11] = (unsigned char)(i >> 24); +#ifdef GIT_EXPERIMENTAL_SHA256 + test_oids[i].oid.type = GIT_OID_SHA1; +#endif } cl_git_pass(git_oidmap_new(&g_map)); @@ -93,9 +96,9 @@ void test_core_oidmap__get_fails_with_nonexisting_key(void) void test_core_oidmap__setting_oid_persists(void) { git_oid oids[] = { - {{ 0x01 }}, - {{ 0x02 }}, - {{ 0x03 }} + GIT_OID_INIT(GIT_OID_SHA1, { 0x01 }), + GIT_OID_INIT(GIT_OID_SHA1, { 0x02 }), + GIT_OID_INIT(GIT_OID_SHA1, { 0x03 }) }; cl_git_pass(git_oidmap_set(g_map, &oids[0], "one")); @@ -110,9 +113,9 @@ void test_core_oidmap__setting_oid_persists(void) void test_core_oidmap__setting_existing_key_updates(void) { git_oid oids[] = { - {{ 0x01 }}, - {{ 0x02 }}, - {{ 0x03 }} + GIT_OID_INIT(GIT_OID_SHA1, { 0x01 }), + GIT_OID_INIT(GIT_OID_SHA1, { 0x02 }), + GIT_OID_INIT(GIT_OID_SHA1, { 0x03 }) }; cl_git_pass(git_oidmap_set(g_map, &oids[0], "one")); diff --git a/tests/libgit2/core/opts.c b/tests/libgit2/core/opts.c index e8f65d510..486ff58c6 100644 --- a/tests/libgit2/core/opts.c +++ b/tests/libgit2/core/opts.c @@ -34,8 +34,9 @@ void test_core_opts__extensions_query(void) cl_git_pass(git_libgit2_opts(GIT_OPT_GET_EXTENSIONS, &out)); - cl_assert_equal_sz(out.count, 1); + cl_assert_equal_sz(out.count, 2); cl_assert_equal_s("noop", out.strings[0]); + cl_assert_equal_s("objectformat", out.strings[1]); git_strarray_dispose(&out); } @@ -48,9 +49,10 @@ void test_core_opts__extensions_add(void) cl_git_pass(git_libgit2_opts(GIT_OPT_SET_EXTENSIONS, in, ARRAY_SIZE(in))); cl_git_pass(git_libgit2_opts(GIT_OPT_GET_EXTENSIONS, &out)); - cl_assert_equal_sz(out.count, 2); + cl_assert_equal_sz(out.count, 3); cl_assert_equal_s("noop", out.strings[0]); - cl_assert_equal_s("foo", out.strings[1]); + cl_assert_equal_s("objectformat", out.strings[1]); + cl_assert_equal_s("foo", out.strings[2]); git_strarray_dispose(&out); } @@ -63,9 +65,10 @@ void test_core_opts__extensions_remove(void) cl_git_pass(git_libgit2_opts(GIT_OPT_SET_EXTENSIONS, in, ARRAY_SIZE(in))); cl_git_pass(git_libgit2_opts(GIT_OPT_GET_EXTENSIONS, &out)); - cl_assert_equal_sz(out.count, 2); - cl_assert_equal_s("bar", out.strings[0]); - cl_assert_equal_s("baz", out.strings[1]); + cl_assert_equal_sz(out.count, 3); + cl_assert_equal_s("objectformat", out.strings[0]); + cl_assert_equal_s("bar", out.strings[1]); + cl_assert_equal_s("baz", out.strings[2]); git_strarray_dispose(&out); } diff --git a/tests/libgit2/core/pool.c b/tests/libgit2/core/pool.c index 5746e35b8..cf01cb9d1 100644 --- a/tests/libgit2/core/pool.c +++ b/tests/libgit2/core/pool.c @@ -7,7 +7,7 @@ static char to_hex[] = "0123456789abcdef"; void test_core_pool__oid(void) { git_pool p; - char oid_hex[GIT_OID_HEXSZ]; + char oid_hex[GIT_OID_SHA1_HEXSIZE]; git_oid *oid; int i, j; @@ -22,12 +22,17 @@ void test_core_pool__oid(void) for (j = 0; j < 8; j++) oid_hex[j] = to_hex[(i >> (4 * j)) & 0x0f]; - cl_git_pass(git_oid_fromstr(oid, oid_hex)); + cl_git_pass(git_oid__fromstr(oid, oid_hex, GIT_OID_SHA1)); } #ifndef GIT_DEBUG_POOL /* with fixed page size, allocation must end up with these values */ + +# ifdef GIT_EXPERIMENTAL_SHA256 + cl_assert_equal_i(sizeof(void *) == 8 ? 90 : 82, git_pool__open_pages(&p)); +# else cl_assert_equal_i(sizeof(void *) == 8 ? 55 : 45, git_pool__open_pages(&p)); +# endif #endif git_pool_clear(&p); } diff --git a/tests/libgit2/core/structinit.c b/tests/libgit2/core/structinit.c index 160e2f612..8a6e48d2a 100644 --- a/tests/libgit2/core/structinit.c +++ b/tests/libgit2/core/structinit.c @@ -160,6 +160,11 @@ void test_core_structinit__compare(void) git_stash_apply_options, GIT_STASH_APPLY_OPTIONS_VERSION, \ GIT_STASH_APPLY_OPTIONS_INIT, git_stash_apply_options_init); + /* stash save */ + CHECK_MACRO_FUNC_INIT_EQUAL( \ + git_stash_save_options, GIT_STASH_SAVE_OPTIONS_VERSION, \ + GIT_STASH_SAVE_OPTIONS_INIT, git_stash_save_options_init); + /* status */ CHECK_MACRO_FUNC_INIT_EQUAL( \ git_status_options, GIT_STATUS_OPTIONS_VERSION, \ diff --git a/tests/libgit2/diff/binary.c b/tests/libgit2/diff/binary.c index 4e71f39c6..3bf39f34a 100644 --- a/tests/libgit2/diff/binary.c +++ b/tests/libgit2/diff/binary.c @@ -31,12 +31,12 @@ static void test_patch( git_patch *patch; git_buf actual = GIT_BUF_INIT; - cl_git_pass(git_oid_fromstr(&id_one, one)); + cl_git_pass(git_oid__fromstr(&id_one, one, GIT_OID_SHA1)); cl_git_pass(git_commit_lookup(&commit_one, repo, &id_one)); cl_git_pass(git_commit_tree(&tree_one, commit_one)); if (two) { - cl_git_pass(git_oid_fromstr(&id_two, two)); + cl_git_pass(git_oid__fromstr(&id_two, two, GIT_OID_SHA1)); cl_git_pass(git_commit_lookup(&commit_two, repo, &id_two)); cl_git_pass(git_commit_tree(&tree_two, commit_two)); } else { @@ -100,7 +100,7 @@ void test_diff_binary__add(void) "\n"; opts.flags = GIT_DIFF_SHOW_BINARY; - opts.id_abbrev = GIT_OID_HEXSZ; + opts.id_abbrev = GIT_OID_SHA1_HEXSIZE; repo = cl_git_sandbox_init("diff_format_email"); test_patch( @@ -183,7 +183,7 @@ void test_diff_binary__delete(void) "\n"; opts.flags = GIT_DIFF_SHOW_BINARY; - opts.id_abbrev = GIT_OID_HEXSZ; + opts.id_abbrev = GIT_OID_SHA1_HEXSIZE; repo = cl_git_sandbox_init("diff_format_email"); test_patch( @@ -215,7 +215,7 @@ void test_diff_binary__delta(void) "\n"; opts.flags = GIT_DIFF_SHOW_BINARY | GIT_DIFF_FORCE_BINARY; - opts.id_abbrev = GIT_OID_HEXSZ; + opts.id_abbrev = GIT_OID_SHA1_HEXSIZE; repo = cl_git_sandbox_init("renames"); cl_git_pass(git_repository_index(&index, repo)); @@ -257,7 +257,7 @@ void test_diff_binary__delta_append(void) "\n"; opts.flags = GIT_DIFF_SHOW_BINARY | GIT_DIFF_FORCE_BINARY; - opts.id_abbrev = GIT_OID_HEXSZ; + opts.id_abbrev = GIT_OID_SHA1_HEXSIZE; repo = cl_git_sandbox_init("renames"); cl_git_pass(git_repository_index(&index, repo)); @@ -285,11 +285,11 @@ void test_diff_binary__empty_for_no_diff(void) git_str actual = GIT_STR_INIT; opts.flags = GIT_DIFF_SHOW_BINARY | GIT_DIFF_FORCE_BINARY; - opts.id_abbrev = GIT_OID_HEXSZ; + opts.id_abbrev = GIT_OID_SHA1_HEXSIZE; repo = cl_git_sandbox_init("renames"); - cl_git_pass(git_oid_fromstr(&id, "19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13")); + cl_git_pass(git_oid__fromstr(&id, "19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13", GIT_OID_SHA1)); cl_git_pass(git_commit_lookup(&commit, repo, &id)); cl_git_pass(git_commit_tree(&tree, commit)); @@ -323,7 +323,7 @@ void test_diff_binary__index_to_workdir(void) "\n"; opts.flags = GIT_DIFF_SHOW_BINARY | GIT_DIFF_FORCE_BINARY; - opts.id_abbrev = GIT_OID_HEXSZ; + opts.id_abbrev = GIT_OID_SHA1_HEXSIZE; repo = cl_git_sandbox_init("renames"); cl_git_pass(git_repository_index(&index, repo)); @@ -389,7 +389,7 @@ void test_diff_binary__print_patch_from_diff(void) "\n"; opts.flags = GIT_DIFF_SHOW_BINARY | GIT_DIFF_FORCE_BINARY; - opts.id_abbrev = GIT_OID_HEXSZ; + opts.id_abbrev = GIT_OID_SHA1_HEXSIZE; repo = cl_git_sandbox_init("renames"); cl_git_pass(git_repository_index(&index, repo)); @@ -501,7 +501,7 @@ void test_diff_binary__blob_to_blob(void) struct diff_data diff_data = {0}; opts.flags = GIT_DIFF_SHOW_BINARY | GIT_DIFF_FORCE_BINARY; - opts.id_abbrev = GIT_OID_HEXSZ; + opts.id_abbrev = GIT_OID_SHA1_HEXSIZE; repo = cl_git_sandbox_init("renames"); cl_git_pass(git_repository_index__weakptr(&index, repo)); @@ -510,8 +510,8 @@ void test_diff_binary__blob_to_blob(void) cl_git_pass(git_index_add_bypath(index, "untimely.txt")); cl_git_pass(git_index_write(index)); - git_oid_fromstr(&old_id, "9a69d960ae94b060f56c2a8702545e2bb1abb935"); - git_oid_fromstr(&new_id, "1111d4f11f4b35bf6759e0fb714fe09731ef0840"); + git_oid__fromstr(&old_id, "9a69d960ae94b060f56c2a8702545e2bb1abb935", GIT_OID_SHA1); + git_oid__fromstr(&new_id, "1111d4f11f4b35bf6759e0fb714fe09731ef0840", GIT_OID_SHA1); cl_git_pass(git_blob_lookup(&old_blob, repo, &old_id)); cl_git_pass(git_blob_lookup(&new_blob, repo, &new_id)); diff --git a/tests/libgit2/diff/blob.c b/tests/libgit2/diff/blob.c index d2f42207d..cb7e48b8d 100644 --- a/tests/libgit2/diff/blob.c +++ b/tests/libgit2/diff/blob.c @@ -45,11 +45,11 @@ void test_diff_blob__initialize(void) memset(&expected, 0, sizeof(expected)); /* tests/resources/attr/root_test4.txt */ - cl_git_pass(git_oid_fromstrn(&oid, "a0f7217a", 8)); + cl_git_pass(git_oid__fromstrn(&oid, "a0f7217a", 8, GIT_OID_SHA1)); cl_git_pass(git_blob_lookup_prefix(&d, g_repo, &oid, 8)); /* alien.png */ - cl_git_pass(git_oid_fromstrn(&oid, "edf3dcee", 8)); + cl_git_pass(git_oid__fromstrn(&oid, "edf3dcee", 8, GIT_OID_SHA1)); cl_git_pass(git_blob_lookup_prefix(&alien, g_repo, &oid, 8)); } @@ -86,10 +86,10 @@ void test_diff_blob__patch_with_freed_blobs(void) git_buf buf = GIT_BUF_INIT; /* tests/resources/attr/root_test1 */ - cl_git_pass(git_oid_fromstrn(&a_oid, "45141a79", 8)); + cl_git_pass(git_oid__fromstrn(&a_oid, "45141a79", 8, GIT_OID_SHA1)); cl_git_pass(git_blob_lookup_prefix(&a, g_repo, &a_oid, 4)); /* tests/resources/attr/root_test2 */ - cl_git_pass(git_oid_fromstrn(&b_oid, "4d713dc4", 8)); + cl_git_pass(git_oid__fromstrn(&b_oid, "4d713dc4", 8, GIT_OID_SHA1)); cl_git_pass(git_blob_lookup_prefix(&b, g_repo, &b_oid, 4)); cl_git_pass(git_patch_from_blobs(&p, a, NULL, b, NULL, NULL)); @@ -110,15 +110,15 @@ void test_diff_blob__can_compare_text_blobs(void) git_oid a_oid, b_oid, c_oid; /* tests/resources/attr/root_test1 */ - cl_git_pass(git_oid_fromstrn(&a_oid, "45141a79", 8)); + cl_git_pass(git_oid__fromstrn(&a_oid, "45141a79", 8, GIT_OID_SHA1)); cl_git_pass(git_blob_lookup_prefix(&a, g_repo, &a_oid, 4)); /* tests/resources/attr/root_test2 */ - cl_git_pass(git_oid_fromstrn(&b_oid, "4d713dc4", 8)); + cl_git_pass(git_oid__fromstrn(&b_oid, "4d713dc4", 8, GIT_OID_SHA1)); cl_git_pass(git_blob_lookup_prefix(&b, g_repo, &b_oid, 4)); /* tests/resources/attr/root_test3 */ - cl_git_pass(git_oid_fromstrn(&c_oid, "c96bbb2c2557a832", 16)); + cl_git_pass(git_oid__fromstrn(&c_oid, "c96bbb2c2557a832", 16, GIT_OID_SHA1)); cl_git_pass(git_blob_lookup_prefix(&c, g_repo, &c_oid, 16)); /* Doing the equivalent of a `git diff -U1` on these files */ @@ -201,15 +201,15 @@ void test_diff_blob__can_compare_text_blobs_with_patch(void) git_patch *p; /* tests/resources/attr/root_test1 */ - cl_git_pass(git_oid_fromstrn(&a_oid, "45141a79", 8)); + cl_git_pass(git_oid__fromstrn(&a_oid, "45141a79", 8, GIT_OID_SHA1)); cl_git_pass(git_blob_lookup_prefix(&a, g_repo, &a_oid, 8)); /* tests/resources/attr/root_test2 */ - cl_git_pass(git_oid_fromstrn(&b_oid, "4d713dc4", 8)); + cl_git_pass(git_oid__fromstrn(&b_oid, "4d713dc4", 8, GIT_OID_SHA1)); cl_git_pass(git_blob_lookup_prefix(&b, g_repo, &b_oid, 8)); /* tests/resources/attr/root_test3 */ - cl_git_pass(git_oid_fromstrn(&c_oid, "c96bbb2c2557a832", 16)); + cl_git_pass(git_oid__fromstrn(&c_oid, "c96bbb2c2557a832", 16, GIT_OID_SHA1)); cl_git_pass(git_blob_lookup_prefix(&c, g_repo, &c_oid, 16)); /* Doing the equivalent of a `git diff -U1` on these files */ @@ -475,7 +475,7 @@ void test_diff_blob__can_compare_two_binary_blobs(void) git_oid h_oid; /* heart.png */ - cl_git_pass(git_oid_fromstrn(&h_oid, "de863bff", 8)); + cl_git_pass(git_oid__fromstrn(&h_oid, "de863bff", 8, GIT_OID_SHA1)); cl_git_pass(git_blob_lookup_prefix(&heart, g_repo, &h_oid, 8)); cl_git_pass(git_diff_blobs( @@ -543,7 +543,7 @@ void test_diff_blob__comparing_two_text_blobs_honors_interhunkcontext(void) opts.context_lines = 3; /* tests/resources/attr/root_test1 from commit f5b0af1 */ - cl_git_pass(git_oid_fromstrn(&old_d_oid, "fe773770", 8)); + cl_git_pass(git_oid__fromstrn(&old_d_oid, "fe773770", 8, GIT_OID_SHA1)); cl_git_pass(git_blob_lookup_prefix(&old_d, g_repo, &old_d_oid, 8)); /* Test with default inter-hunk-context (not set) => default is 0 */ @@ -652,7 +652,7 @@ void test_diff_blob__can_compare_blob_to_buffer(void) const char *b_content = "Hello from the root\n\nSome additional lines\n\nDown here below\n\n"; /* tests/resources/attr/root_test1 */ - cl_git_pass(git_oid_fromstrn(&a_oid, "45141a79", 8)); + cl_git_pass(git_oid__fromstrn(&a_oid, "45141a79", 8, GIT_OID_SHA1)); cl_git_pass(git_blob_lookup_prefix(&a, g_repo, &a_oid, 8)); /* diff from blob a to content of b */ @@ -694,7 +694,7 @@ void test_diff_blob__can_compare_blob_to_buffer_with_patch(void) size_t tc, ta, td; /* tests/resources/attr/root_test1 */ - cl_git_pass(git_oid_fromstrn(&a_oid, "45141a79", 8)); + cl_git_pass(git_oid__fromstrn(&a_oid, "45141a79", 8, GIT_OID_SHA1)); cl_git_pass(git_blob_lookup_prefix(&a, g_repo, &a_oid, 8)); /* diff from blob a to content of b */ @@ -773,10 +773,10 @@ void test_diff_blob__binary_data_comparisons(void) opts.flags |= GIT_DIFF_INCLUDE_UNMODIFIED; - cl_git_pass(git_oid_fromstrn(&oid, "45141a79", 8)); + cl_git_pass(git_oid__fromstrn(&oid, "45141a79", 8, GIT_OID_SHA1)); cl_git_pass(git_blob_lookup_prefix(&nonbin, g_repo, &oid, 8)); - cl_git_pass(git_oid_fromstrn(&oid, "b435cd56", 8)); + cl_git_pass(git_oid__fromstrn(&oid, "b435cd56", 8, GIT_OID_SHA1)); cl_git_pass(git_blob_lookup_prefix(&bin, g_repo, &oid, 8)); /* non-binary to reference content */ @@ -879,11 +879,11 @@ void test_diff_blob__using_path_and_attributes(void) opts.context_lines = 0; opts.flags |= GIT_DIFF_INCLUDE_UNMODIFIED; - cl_git_pass(git_oid_fromstrn(&oid, "45141a79", 8)); + cl_git_pass(git_oid__fromstrn(&oid, "45141a79", 8, GIT_OID_SHA1)); cl_git_pass(git_blob_lookup_prefix(&nonbin, g_repo, &oid, 8)); /* 20b: "Hello from the root\n" */ - cl_git_pass(git_oid_fromstrn(&oid, "b435cd56", 8)); + cl_git_pass(git_oid__fromstrn(&oid, "b435cd56", 8, GIT_OID_SHA1)); cl_git_pass(git_blob_lookup_prefix(&bin, g_repo, &oid, 8)); /* 33b: "0123456789\n\x01\x02\x03\x04\x05\x06\x07\x08\x09\n0123456789\n" */ diff --git a/tests/libgit2/diff/diff_helpers.c b/tests/libgit2/diff/diff_helpers.c index e9900339f..341b0a448 100644 --- a/tests/libgit2/diff/diff_helpers.c +++ b/tests/libgit2/diff/diff_helpers.c @@ -11,7 +11,7 @@ git_tree *resolve_commit_oid_to_tree( git_object *obj = NULL; git_tree *tree = NULL; - if (git_oid_fromstrn(&oid, partial_oid, len) == 0) + if (git_oid__fromstrn(&oid, partial_oid, len, GIT_OID_SHA1) == 0) cl_git_pass(git_object_lookup_prefix(&obj, repo, &oid, len, GIT_OBJECT_ANY)); cl_git_pass(git_object_peel((git_object **) &tree, obj, GIT_OBJECT_TREE)); diff --git a/tests/libgit2/diff/format_email.c b/tests/libgit2/diff/format_email.c index 612804c42..2726edb0d 100644 --- a/tests/libgit2/diff/format_email.c +++ b/tests/libgit2/diff/format_email.c @@ -28,7 +28,7 @@ static void assert_email_match( git_diff *diff = NULL; git_buf buf = GIT_BUF_INIT; - git_oid_fromstr(&oid, oidstr); + git_oid__fromstr(&oid, oidstr, GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &oid)); @@ -228,7 +228,7 @@ void test_diff_format_email__multiple(void) "\n"; - git_oid_fromstr(&oid, "10808fe9c9be5a190c0ba68d1a002233fb363508"); + git_oid__fromstr(&oid, "10808fe9c9be5a190c0ba68d1a002233fb363508", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &oid)); opts.id = git_commit_id(commit); @@ -245,7 +245,7 @@ void test_diff_format_email__multiple(void) diff = NULL; commit = NULL; - git_oid_fromstr(&oid, "873806f6f27e631eb0b23e4b56bea2bfac14a373"); + git_oid__fromstr(&oid, "873806f6f27e631eb0b23e4b56bea2bfac14a373", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &oid)); opts.id = git_commit_id(commit); @@ -324,7 +324,7 @@ void test_diff_format_email__invalid_no(void) git_diff_format_email_options opts = GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT; git_buf buf = GIT_BUF_INIT; - git_oid_fromstr(&oid, "9264b96c6d104d0e07ae33d3007b6a48246c6f92"); + git_oid__fromstr(&oid, "9264b96c6d104d0e07ae33d3007b6a48246c6f92", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &oid)); diff --git a/tests/libgit2/diff/index.c b/tests/libgit2/diff/index.c index b616a372b..5773b748e 100644 --- a/tests/libgit2/diff/index.c +++ b/tests/libgit2/diff/index.c @@ -185,9 +185,9 @@ static void do_conflicted_diff(diff_expects *exp, unsigned long flags) ancestor.path = ours.path = theirs.path = "staged_changes"; ancestor.mode = ours.mode = theirs.mode = GIT_FILEMODE_BLOB; - git_oid_fromstr(&ancestor.id, "d427e0b2e138501a3d15cc376077a3631e15bd46"); - git_oid_fromstr(&ours.id, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf"); - git_oid_fromstr(&theirs.id, "2bd0a343aeef7a2cf0d158478966a6e587ff3863"); + git_oid__fromstr(&ancestor.id, "d427e0b2e138501a3d15cc376077a3631e15bd46", GIT_OID_SHA1); + git_oid__fromstr(&ours.id, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf", GIT_OID_SHA1); + git_oid__fromstr(&theirs.id, "2bd0a343aeef7a2cf0d158478966a6e587ff3863", GIT_OID_SHA1); cl_git_pass(git_index_conflict_add(index, &ancestor, &ours, &theirs)); cl_git_pass(git_diff_tree_to_index(&diff, g_repo, a, index, &opts)); @@ -255,7 +255,7 @@ void test_diff_index__not_in_head_conflicted(void) theirs.path = "file_not_in_head"; theirs.mode = GIT_FILEMODE_BLOB; - git_oid_fromstr(&theirs.id, "2bd0a343aeef7a2cf0d158478966a6e587ff3863"); + git_oid__fromstr(&theirs.id, "2bd0a343aeef7a2cf0d158478966a6e587ff3863", GIT_OID_SHA1); cl_git_pass(git_index_conflict_add(index, NULL, NULL, &theirs)); cl_git_pass(git_diff_tree_to_index(&diff, g_repo, a, index, NULL)); diff --git a/tests/libgit2/diff/parse.c b/tests/libgit2/diff/parse.c index 9c3f798e4..cae843cc8 100644 --- a/tests/libgit2/diff/parse.c +++ b/tests/libgit2/diff/parse.c @@ -151,7 +151,7 @@ static void test_tree_to_tree_computed_to_parsed( repo = cl_git_sandbox_init(sandbox); - opts.id_abbrev = GIT_OID_HEXSZ; + opts.id_abbrev = GIT_OID_SHA1_HEXSIZE; opts.flags = GIT_DIFF_SHOW_BINARY | diff_flags; findopts.flags = find_flags; diff --git a/tests/libgit2/diff/patchid.c b/tests/libgit2/diff/patchid.c index 621a720f7..1cc368e21 100644 --- a/tests/libgit2/diff/patchid.c +++ b/tests/libgit2/diff/patchid.c @@ -6,7 +6,7 @@ static void verify_patch_id(const char *diff_content, const char *expected_id) git_oid expected_oid, actual_oid; git_diff *diff; - cl_git_pass(git_oid_fromstr(&expected_oid, expected_id)); + cl_git_pass(git_oid__fromstr(&expected_oid, expected_id, GIT_OID_SHA1)); cl_git_pass(git_diff_from_buffer(&diff, diff_content, strlen(diff_content))); cl_git_pass(git_diff_patchid(&actual_oid, diff, NULL)); diff --git a/tests/libgit2/diff/rename.c b/tests/libgit2/diff/rename.c index 30e9ea432..9d4439462 100644 --- a/tests/libgit2/diff/rename.c +++ b/tests/libgit2/diff/rename.c @@ -574,7 +574,7 @@ void test_diff_rename__working_directory_changes(void) /* again with exact match blob */ - cl_git_pass(git_oid_fromstr(&id, blobsha)); + cl_git_pass(git_oid__fromstr(&id, blobsha, GIT_OID_SHA1)); cl_git_pass(git_blob_lookup(&blob, g_repo, &id)); cl_git_pass(git_str_set( &content, git_blob_rawcontent(blob), (size_t)git_blob_rawsize(blob))); diff --git a/tests/libgit2/diff/stats.c b/tests/libgit2/diff/stats.c index f69dba9b3..b076ad5a9 100644 --- a/tests/libgit2/diff/stats.c +++ b/tests/libgit2/diff/stats.c @@ -26,7 +26,7 @@ static void diff_stats_from_commit_oid( git_commit *commit; git_diff *diff; - git_oid_fromstr(&oid, oidstr); + git_oid__fromstr(&oid, oidstr, GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, _repo, &oid)); cl_git_pass(git_diff__commit(&diff, _repo, commit, NULL)); if (rename) diff --git a/tests/libgit2/diff/workdir.c b/tests/libgit2/diff/workdir.c index 20e000906..21c5b0de9 100644 --- a/tests/libgit2/diff/workdir.c +++ b/tests/libgit2/diff/workdir.c @@ -86,11 +86,11 @@ void test_diff_workdir__to_index_with_conflicts(void) /* Adding an entry that represents a rename gets two files in conflict */ our_entry.path = "subdir/modified_file"; our_entry.mode = 0100644; - git_oid_fromstr(&our_entry.id, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf"); + git_oid__fromstr(&our_entry.id, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf", GIT_OID_SHA1); their_entry.path = "subdir/rename_conflict"; their_entry.mode = 0100644; - git_oid_fromstr(&their_entry.id, "2bd0a343aeef7a2cf0d158478966a6e587ff3863"); + git_oid__fromstr(&their_entry.id, "2bd0a343aeef7a2cf0d158478966a6e587ff3863", GIT_OID_SHA1); cl_git_pass(git_repository_index(&index, g_repo)); cl_git_pass(git_index_conflict_add(index, NULL, &our_entry, &their_entry)); @@ -1232,6 +1232,42 @@ void test_diff_workdir__checks_options_version(void) cl_assert_equal_i(GIT_ERROR_INVALID, err->klass); } +void test_diff_workdir__can_diff_empty_untracked_file(void) +{ + git_diff_options opts = GIT_DIFF_OPTIONS_INIT; + git_diff *diff = NULL; + git_patch *patch = NULL; + + g_repo = cl_git_sandbox_init("empty_standard_repo"); + + cl_git_mkfile("empty_standard_repo/emptyfile.txt", ""); + + opts.context_lines = 3; + opts.interhunk_lines = 1; + opts.flags |= GIT_DIFF_INCLUDE_UNTRACKED | GIT_DIFF_SHOW_UNTRACKED_CONTENT; + + cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts)); + + /* without filters */ + git_patch_from_diff(&patch, diff, 0); + cl_assert(NULL != patch); + cl_assert(0 == git_patch_get_delta(patch)->new_file.size); + cl_assert(0 == strcmp("emptyfile.txt", git_patch_get_delta(patch)->new_file.path)); + git_patch_free(patch); + patch = NULL; + + /* with a filter */ + cl_repo_set_bool(g_repo, "core.autocrlf", true); /* install some filter */ + git_patch_from_diff(&patch, diff, 0); + cl_assert(NULL != patch); + cl_assert(0 == git_patch_get_delta(patch)->new_file.size); + cl_assert(0 == strcmp("emptyfile.txt", git_patch_get_delta(patch)->new_file.path)); + git_patch_free(patch); + patch = NULL; + + git_diff_free(diff); +} + void test_diff_workdir__can_diff_empty_file(void) { git_diff *diff; @@ -1979,9 +2015,9 @@ void test_diff_workdir__to_index_conflicted(void) { ancestor.path = ours.path = theirs.path = "_file"; ancestor.mode = ours.mode = theirs.mode = 0100644; - git_oid_fromstr(&ancestor.id, "d427e0b2e138501a3d15cc376077a3631e15bd46"); - git_oid_fromstr(&ours.id, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf"); - git_oid_fromstr(&theirs.id, "2bd0a343aeef7a2cf0d158478966a6e587ff3863"); + git_oid__fromstr(&ancestor.id, "d427e0b2e138501a3d15cc376077a3631e15bd46", GIT_OID_SHA1); + git_oid__fromstr(&ours.id, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf", GIT_OID_SHA1); + git_oid__fromstr(&theirs.id, "2bd0a343aeef7a2cf0d158478966a6e587ff3863", GIT_OID_SHA1); cl_git_pass(git_index_conflict_add(index, &ancestor, &ours, &theirs)); cl_git_pass(git_diff_tree_to_index(&diff1, g_repo, a, index, NULL)); diff --git a/tests/libgit2/email/create.c b/tests/libgit2/email/create.c index 27a665582..cf40ff552 100644 --- a/tests/libgit2/email/create.c +++ b/tests/libgit2/email/create.c @@ -24,7 +24,7 @@ static void email_for_commit( git_commit *commit = NULL; git_diff *diff = NULL; - git_oid_fromstr(&oid, commit_id); + git_oid__fromstr(&oid, commit_id, GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &oid)); @@ -323,7 +323,7 @@ void test_email_create__custom_summary_and_body(void) opts.subject_prefix = "PPPPPATCH"; - git_oid_fromstr(&oid, "627e7e12d87e07a83fad5b6bfa25e86ead4a5270"); + git_oid__fromstr(&oid, "627e7e12d87e07a83fad5b6bfa25e86ead4a5270", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &oid)); cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); cl_git_pass(git_email_create_from_diff(&buf, diff, 2, 4, &oid, summary, body, git_commit_author(commit), &opts)); diff --git a/tests/libgit2/email/create.c.bak b/tests/libgit2/email/create.c.bak deleted file mode 100644 index 3bb95a6f6..000000000 --- a/tests/libgit2/email/create.c.bak +++ /dev/null @@ -1,386 +0,0 @@ -#include "clar.h" -#include "clar_libgit2.h" - -#include "buffer.h" -#include "diff_generate.h" - -static git_repository *repo; - -void test_email_create__initialize(void) -{ - repo = cl_git_sandbox_init("diff_format_email"); -} - -void test_email_create__cleanup(void) -{ - cl_git_sandbox_cleanup(); -} - -static void email_for_commit( - git_buf *out, - const char *commit_id, - git_email_create_options *opts) -{ - git_oid oid; - git_commit *commit = NULL; - git_diff *diff = NULL; - - git_oid_fromstr(&oid, commit_id); - - cl_git_pass(git_commit_lookup(&commit, repo, &oid)); - - cl_git_pass(git_email_create_from_commit(out, commit, opts)); - - git_diff_free(diff); - git_commit_free(commit); -} - -static void assert_email_match( - const char *expected, - const char *commit_id, - git_email_create_options *opts) -{ - git_buf buf = GIT_BUF_INIT; - - email_for_commit(&buf, commit_id, opts); - cl_assert_equal_s(expected, git_buf_cstr(&buf)); - - git_buf_dispose(&buf); -} - -static void assert_subject_match( - const char *expected, - const char *commit_id, - git_email_create_options *opts) -{ - git_buf buf = GIT_BUF_INIT; - const char *loc; - - email_for_commit(&buf, commit_id, opts); - - cl_assert((loc = strstr(buf.ptr, "\nSubject: ")) != NULL); - git_buf_consume(&buf, (loc + 10)); - git_buf_truncate_at_char(&buf, '\n'); - - cl_assert_equal_s(expected, git_buf_cstr(&buf)); - - git_buf_dispose(&buf); -} - -void test_email_create__commit(void) -{ - const char *expected = - "From 9264b96c6d104d0e07ae33d3007b6a48246c6f92 Mon Sep 17 00:00:00 2001\n" \ - "From: Jacques Germishuys \n" \ - "Date: Wed, 9 Apr 2014 20:57:01 +0200\n" \ - "Subject: [PATCH] Modify some content\n" \ - "\n" \ - "---\n" \ - " file1.txt | 8 +++++---\n" \ - " 1 file changed, 5 insertions(+), 3 deletions(-)\n" \ - "\n" \ - "diff --git a/file1.txt b/file1.txt\n" \ - "index 94aaae8..af8f41d 100644\n" \ - "--- a/file1.txt\n" \ - "+++ b/file1.txt\n" \ - "@@ -1,15 +1,17 @@\n" \ - " file1.txt\n" \ - " file1.txt\n" \ - "+_file1.txt_\n" \ - " file1.txt\n" \ - " file1.txt\n" \ - " file1.txt\n" \ - " file1.txt\n" \ - "+\n" \ - "+\n" \ - " file1.txt\n" \ - " file1.txt\n" \ - " file1.txt\n" \ - " file1.txt\n" \ - " file1.txt\n" \ - "-file1.txt\n" \ - "-file1.txt\n" \ - "-file1.txt\n" \ - "+_file1.txt_\n" \ - "+_file1.txt_\n" \ - " file1.txt\n" \ - "--\n" \ - "libgit2 " LIBGIT2_VERSION "\n" \ - "\n"; - - assert_email_match( - expected, "9264b96c6d104d0e07ae33d3007b6a48246c6f92", NULL); -} - -void test_email_create__custom_summary_and_body(void) -{ - const char *expected = "From 627e7e12d87e07a83fad5b6bfa25e86ead4a5270 Mon Sep 17 00:00:00 2001\n" \ - "From: Patrick Steinhardt \n" \ - "Date: Tue, 24 Nov 2015 13:34:39 +0100\n" \ - "Subject: [PPPPPATCH 2/4] This is a subject\n" \ - "\n" \ - "Modify content of file3.txt by appending a new line. Make this\n" \ - "commit message somewhat longer to test behavior with newlines\n" \ - "embedded in the message body.\n" \ - "\n" \ - "Also test if new paragraphs are included correctly.\n" \ - "---\n" \ - " file3.txt | 1 +\n" \ - " 1 file changed, 1 insertion(+)\n" \ - "\n" \ - "diff --git a/file3.txt b/file3.txt\n" \ - "index 9a2d780..7309653 100644\n" \ - "--- a/file3.txt\n" \ - "+++ b/file3.txt\n" \ - "@@ -3,3 +3,4 @@ file3!\n" \ - " file3\n" \ - " file3\n" \ - " file3\n" \ - "+file3\n" \ - "--\n" \ - "libgit2 " LIBGIT2_VERSION "\n" \ - "\n"; - - const char *summary = "This is a subject\nwith\nnewlines"; - const char *body = "Modify content of file3.txt by appending a new line. Make this\n" \ - "commit message somewhat longer to test behavior with newlines\n" \ - "embedded in the message body.\n" \ - "\n" \ - "Also test if new paragraphs are included correctly."; - - git_oid oid; - git_commit *commit = NULL; - git_diff *diff = NULL; - git_buf buf = GIT_BUF_INIT; - git_email_create_options opts = GIT_EMAIL_CREATE_OPTIONS_INIT; - - opts.subject_prefix = "PPPPPATCH"; - - git_oid_fromstr(&oid, "627e7e12d87e07a83fad5b6bfa25e86ead4a5270"); - cl_git_pass(git_commit_lookup(&commit, repo, &oid)); - cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); - cl_git_pass(git_email_create_from_diff(&buf, diff, 2, 4, &oid, summary, body, git_commit_author(commit), &opts)); - - cl_assert_equal_s(expected, git_buf_cstr(&buf)); - - git_diff_free(diff); - git_commit_free(commit); - git_buf_dispose(&buf); -} - -void test_email_create__mode_change(void) -{ - const char *expected = - "From 7ade76dd34bba4733cf9878079f9fd4a456a9189 Mon Sep 17 00:00:00 2001\n" \ - "From: Jacques Germishuys \n" \ - "Date: Thu, 10 Apr 2014 10:05:03 +0200\n" \ - "Subject: [PATCH] Update permissions\n" \ - "\n" \ - "---\n" \ - " file1.txt.renamed | 0\n" \ - " 1 file changed, 0 insertions(+), 0 deletions(-)\n" \ - " mode change 100644 => 100755 file1.txt.renamed\n" \ - "\n" \ - "diff --git a/file1.txt.renamed b/file1.txt.renamed\n" \ - "old mode 100644\n" \ - "new mode 100755\n" \ - "--\n" \ - "libgit2 " LIBGIT2_VERSION "\n" \ - "\n"; - - assert_email_match(expected, "7ade76dd34bba4733cf9878079f9fd4a456a9189", NULL); -} - -void test_email_create__rename(void) -{ - const char *expected = - "From 6e05acc5a5dab507d91a0a0cc0fb05a3dd98892d Mon Sep 17 00:00:00 2001\n" \ - "From: Jacques Germishuys \n" \ - "Date: Wed, 9 Apr 2014 21:15:56 +0200\n" \ - "Subject: [PATCH] Renamed file1.txt -> file1.txt.renamed\n" \ - "\n" \ - "---\n" \ - " file1.txt => file1.txt.renamed | 4 ++--\n" \ - " 1 file changed, 2 insertions(+), 2 deletions(-)\n" \ - "\n" \ - "diff --git a/file1.txt b/file1.txt.renamed\n" \ - "similarity index 86%\n" \ - "rename from file1.txt\n" \ - "rename to file1.txt.renamed\n" \ - "index af8f41d..a97157a 100644\n" \ - "--- a/file1.txt\n" \ - "+++ b/file1.txt.renamed\n" \ - "@@ -3,13 +3,13 @@ file1.txt\n" \ - " _file1.txt_\n" \ - " file1.txt\n" \ - " file1.txt\n" \ - "-file1.txt\n" \ - "+file1.txt_renamed\n" \ - " file1.txt\n" \ - " \n" \ - " \n" \ - " file1.txt\n" \ - " file1.txt\n" \ - "-file1.txt\n" \ - "+file1.txt_renamed\n" \ - " file1.txt\n" \ - " file1.txt\n" \ - " _file1.txt_\n" \ - "--\n" \ - "libgit2 " LIBGIT2_VERSION "\n" \ - "\n"; - - assert_email_match(expected, "6e05acc5a5dab507d91a0a0cc0fb05a3dd98892d", NULL); -} - -void test_email_create__rename_as_add_delete(void) -{ - const char *expected = - "From 6e05acc5a5dab507d91a0a0cc0fb05a3dd98892d Mon Sep 17 00:00:00 2001\n" \ - "From: Jacques Germishuys \n" \ - "Date: Wed, 9 Apr 2014 21:15:56 +0200\n" \ - "Subject: [PATCH] Renamed file1.txt -> file1.txt.renamed\n" \ - "\n" \ - "---\n" \ - " file1.txt | 17 -----------------\n" \ - " file1.txt.renamed | 17 +++++++++++++++++\n" \ - " 2 files changed, 17 insertions(+), 17 deletions(-)\n" \ - " delete mode 100644 file1.txt\n" \ - " create mode 100644 file1.txt.renamed\n" \ - "\n" \ - "diff --git a/file1.txt b/file1.txt\n" \ - "deleted file mode 100644\n" \ - "index af8f41d..0000000\n" \ - "--- a/file1.txt\n" \ - "+++ /dev/null\n" \ - "@@ -1,17 +0,0 @@\n" \ - "-file1.txt\n" \ - "-file1.txt\n" \ - "-_file1.txt_\n" \ - "-file1.txt\n" \ - "-file1.txt\n" \ - "-file1.txt\n" \ - "-file1.txt\n" \ - "-\n" \ - "-\n" \ - "-file1.txt\n" \ - "-file1.txt\n" \ - "-file1.txt\n" \ - "-file1.txt\n" \ - "-file1.txt\n" \ - "-_file1.txt_\n" \ - "-_file1.txt_\n" \ - "-file1.txt\n" \ - "diff --git a/file1.txt.renamed b/file1.txt.renamed\n" \ - "new file mode 100644\n" \ - "index 0000000..a97157a\n" \ - "--- /dev/null\n" \ - "+++ b/file1.txt.renamed\n" \ - "@@ -0,0 +1,17 @@\n" \ - "+file1.txt\n" \ - "+file1.txt\n" \ - "+_file1.txt_\n" \ - "+file1.txt\n" \ - "+file1.txt\n" \ - "+file1.txt_renamed\n" \ - "+file1.txt\n" \ - "+\n" \ - "+\n" \ - "+file1.txt\n" \ - "+file1.txt\n" \ - "+file1.txt_renamed\n" \ - "+file1.txt\n" \ - "+file1.txt\n" \ - "+_file1.txt_\n" \ - "+_file1.txt_\n" \ - "+file1.txt\n" \ - "--\n" \ - "libgit2 " LIBGIT2_VERSION "\n" \ - "\n"; - - git_email_create_options opts = GIT_EMAIL_CREATE_OPTIONS_INIT; - opts.flags |= GIT_EMAIL_CREATE_NO_RENAMES; - - assert_email_match(expected, "6e05acc5a5dab507d91a0a0cc0fb05a3dd98892d", &opts); -} - -void test_email_create__binary(void) -{ - const char *expected = - "From 8d7523f6fcb2404257889abe0d96f093d9f524f9 Mon Sep 17 00:00:00 2001\n" \ - "From: Jacques Germishuys \n" \ - "Date: Sun, 13 Apr 2014 18:10:18 +0200\n" \ - "Subject: [PATCH] Modified binary file\n" \ - "\n" \ - "---\n" \ - " binary.bin | Bin 3 -> 5 bytes\n" \ - " 1 file changed, 0 insertions(+), 0 deletions(-)\n" \ - "\n" \ - "diff --git a/binary.bin b/binary.bin\n" \ - "index bd474b2519cc15eab801ff851cc7d50f0dee49a1..9ac35ff15cd8864aeafd889e4826a3150f0b06c4 100644\n" \ - "GIT binary patch\n" \ - "literal 5\n" \ - "Mc${NkU}WL~000&M4gdfE\n" \ - "\n" \ - "literal 3\n" \ - "Kc${Nk-~s>u4FC%O\n" \ - "\n" \ - "--\n" \ - "libgit2 " LIBGIT2_VERSION "\n" \ - "\n"; - - assert_email_match(expected, "8d7523f6fcb2404257889abe0d96f093d9f524f9", NULL); -} - -void test_email_create__binary_not_included(void) -{ - const char *expected = - "From 8d7523f6fcb2404257889abe0d96f093d9f524f9 Mon Sep 17 00:00:00 2001\n" \ - "From: Jacques Germishuys \n" \ - "Date: Sun, 13 Apr 2014 18:10:18 +0200\n" \ - "Subject: [PATCH] Modified binary file\n" \ - "\n" \ - "---\n" \ - " binary.bin | Bin 3 -> 5 bytes\n" \ - " 1 file changed, 0 insertions(+), 0 deletions(-)\n" \ - "\n" \ - "diff --git a/binary.bin b/binary.bin\n" \ - "index bd474b2..9ac35ff 100644\n" \ - "Binary files a/binary.bin and b/binary.bin differ\n" \ - "--\n" \ - "libgit2 " LIBGIT2_VERSION "\n" \ - "\n"; - - git_email_create_options opts = GIT_EMAIL_CREATE_OPTIONS_INIT; - opts.diff_opts.flags &= ~GIT_DIFF_SHOW_BINARY; - - assert_email_match(expected, "8d7523f6fcb2404257889abe0d96f093d9f524f9", &opts); -} - -void test_email_create__commit_subjects(void) -{ - git_email_create_options opts = GIT_EMAIL_CREATE_OPTIONS_INIT; - - assert_subject_match("[PATCH] Modify some content", "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts); - - opts.reroll_number = 42; - assert_subject_match("[PATCH v42] Modify some content", "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts); - - opts.flags |= GIT_EMAIL_CREATE_ALWAYS_NUMBER; - assert_subject_match("[PATCH v42 1/1] Modify some content", "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts); - - opts.start_number = 9; - assert_subject_match("[PATCH v42 9/9] Modify some content", "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts); - - opts.subject_prefix = ""; - assert_subject_match("[v42 9/9] Modify some content", "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts); - - opts.reroll_number = 0; - assert_subject_match("[9/9] Modify some content", "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts); - - opts.start_number = 0; - assert_subject_match("[1/1] Modify some content", "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts); - - opts.flags = GIT_EMAIL_CREATE_OMIT_NUMBERS; - assert_subject_match("Modify some content", "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts); -} diff --git a/tests/libgit2/fetch/local.c b/tests/libgit2/fetch/local.c index 20bd7adf4..5d2417f1c 100644 --- a/tests/libgit2/fetch/local.c +++ b/tests/libgit2/fetch/local.c @@ -26,7 +26,7 @@ void test_fetch_local__defaults(void) cl_fixture("testrepo.git"))); cl_git_pass(git_remote_fetch(remote, NULL, NULL, NULL)); - git_oid_fromstr(&expected_id, "258f0e2a959a364e40ed6603d5d44fbb24765b10"); + git_oid__fromstr(&expected_id, "258f0e2a959a364e40ed6603d5d44fbb24765b10", GIT_OID_SHA1); cl_git_pass(git_revparse_single(&obj, repo, "refs/remotes/test/haacked")); cl_assert_equal_oid(&expected_id, git_object_id(obj)); @@ -47,7 +47,7 @@ void test_fetch_local__reachable_commit(void) refspecs.strings = &refspec; refspecs.count = 1; - git_oid_fromstr(&expected_id, "5b5b025afb0b4c913b4c338a42934a3863bf3644"); + git_oid__fromstr(&expected_id, "5b5b025afb0b4c913b4c338a42934a3863bf3644", GIT_OID_SHA1); cl_git_pass(git_remote_create(&remote, repo, "test", cl_fixture("testrepo.git"))); diff --git a/tests/libgit2/fetchhead/nonetwork.c b/tests/libgit2/fetchhead/nonetwork.c index aadcc7880..2519d895e 100644 --- a/tests/libgit2/fetchhead/nonetwork.c +++ b/tests/libgit2/fetchhead/nonetwork.c @@ -29,43 +29,49 @@ static void populate_fetchhead(git_vector *out, git_repository *repo) git_fetchhead_ref *fetchhead_ref; git_oid oid; - cl_git_pass(git_oid_fromstr(&oid, - "49322bb17d3acc9146f98c97d078513228bbf3c0")); + cl_git_pass(git_oid__fromstr(&oid, + "49322bb17d3acc9146f98c97d078513228bbf3c0", + GIT_OID_SHA1)); cl_git_pass(git_fetchhead_ref_create(&fetchhead_ref, &oid, 1, "refs/heads/master", "https://github.com/libgit2/TestGitRepository")); cl_git_pass(git_vector_insert(out, fetchhead_ref)); - cl_git_pass(git_oid_fromstr(&oid, - "0966a434eb1a025db6b71485ab63a3bfbea520b6")); + cl_git_pass(git_oid__fromstr(&oid, + "0966a434eb1a025db6b71485ab63a3bfbea520b6", + GIT_OID_SHA1)); cl_git_pass(git_fetchhead_ref_create(&fetchhead_ref, &oid, 0, "refs/heads/first-merge", "https://github.com/libgit2/TestGitRepository")); cl_git_pass(git_vector_insert(out, fetchhead_ref)); - cl_git_pass(git_oid_fromstr(&oid, - "42e4e7c5e507e113ebbb7801b16b52cf867b7ce1")); + cl_git_pass(git_oid__fromstr(&oid, + "42e4e7c5e507e113ebbb7801b16b52cf867b7ce1", + GIT_OID_SHA1)); cl_git_pass(git_fetchhead_ref_create(&fetchhead_ref, &oid, 0, "refs/heads/no-parent", "https://github.com/libgit2/TestGitRepository")); cl_git_pass(git_vector_insert(out, fetchhead_ref)); - cl_git_pass(git_oid_fromstr(&oid, - "d96c4e80345534eccee5ac7b07fc7603b56124cb")); + cl_git_pass(git_oid__fromstr(&oid, + "d96c4e80345534eccee5ac7b07fc7603b56124cb", + GIT_OID_SHA1)); cl_git_pass(git_fetchhead_ref_create(&fetchhead_ref, &oid, 0, "refs/tags/annotated_tag", "https://github.com/libgit2/TestGitRepository")); cl_git_pass(git_vector_insert(out, fetchhead_ref)); - cl_git_pass(git_oid_fromstr(&oid, - "55a1a760df4b86a02094a904dfa511deb5655905")); + cl_git_pass(git_oid__fromstr(&oid, + "55a1a760df4b86a02094a904dfa511deb5655905", + GIT_OID_SHA1)); cl_git_pass(git_fetchhead_ref_create(&fetchhead_ref, &oid, 0, "refs/tags/blob", "https://github.com/libgit2/TestGitRepository")); cl_git_pass(git_vector_insert(out, fetchhead_ref)); - cl_git_pass(git_oid_fromstr(&oid, - "8f50ba15d49353813cc6e20298002c0d17b0a9ee")); + cl_git_pass(git_oid__fromstr(&oid, + "8f50ba15d49353813cc6e20298002c0d17b0a9ee", + GIT_OID_SHA1)); cl_git_pass(git_fetchhead_ref_create(&fetchhead_ref, &oid, 0, "refs/tags/commit_tree", "https://github.com/libgit2/TestGitRepository")); @@ -170,7 +176,7 @@ static int read_old_style_cb(const char *name, const char *url, GIT_UNUSED(payload); - git_oid_fromstr(&expected, "49322bb17d3acc9146f98c97d078513228bbf3c0"); + git_oid__fromstr(&expected, "49322bb17d3acc9146f98c97d078513228bbf3c0", GIT_OID_SHA1); cl_assert(name == NULL); cl_assert(url == NULL); @@ -197,7 +203,7 @@ static int read_type_missing(const char *ref_name, const char *remote_url, GIT_UNUSED(payload); - git_oid_fromstr(&expected, "49322bb17d3acc9146f98c97d078513228bbf3c0"); + git_oid__fromstr(&expected, "49322bb17d3acc9146f98c97d078513228bbf3c0", GIT_OID_SHA1); cl_assert_equal_s("name", ref_name); cl_assert_equal_s("remote_url", remote_url); @@ -224,7 +230,7 @@ static int read_name_missing(const char *ref_name, const char *remote_url, GIT_UNUSED(payload); - git_oid_fromstr(&expected, "49322bb17d3acc9146f98c97d078513228bbf3c0"); + git_oid__fromstr(&expected, "49322bb17d3acc9146f98c97d078513228bbf3c0", GIT_OID_SHA1); cl_assert(ref_name == NULL); cl_assert_equal_s("remote_url", remote_url); @@ -528,13 +534,13 @@ void test_fetchhead_nonetwork__credentials_are_stripped(void) git_fetchhead_ref *ref; git_oid oid; - cl_git_pass(git_oid_fromstr(&oid, "49322bb17d3acc9146f98c97d078513228bbf3c0")); + cl_git_pass(git_oid__fromstr(&oid, "49322bb17d3acc9146f98c97d078513228bbf3c0", GIT_OID_SHA1)); cl_git_pass(git_fetchhead_ref_create(&ref, &oid, 0, "refs/tags/commit_tree", "http://foo:bar@github.com/libgit2/TestGitRepository")); cl_assert_equal_s(ref->remote_url, "http://github.com/libgit2/TestGitRepository"); git_fetchhead_ref_free(ref); - cl_git_pass(git_oid_fromstr(&oid, "49322bb17d3acc9146f98c97d078513228bbf3c0")); + cl_git_pass(git_oid__fromstr(&oid, "49322bb17d3acc9146f98c97d078513228bbf3c0", GIT_OID_SHA1)); cl_git_pass(git_fetchhead_ref_create(&ref, &oid, 0, "refs/tags/commit_tree", "https://foo:bar@github.com/libgit2/TestGitRepository")); cl_assert_equal_s(ref->remote_url, "https://github.com/libgit2/TestGitRepository"); diff --git a/tests/libgit2/filter/bare.c b/tests/libgit2/filter/bare.c index 8402638ce..f53cfcb49 100644 --- a/tests/libgit2/filter/bare.c +++ b/tests/libgit2/filter/bare.c @@ -140,7 +140,7 @@ void test_filter_bare__from_specific_commit_one(void) opts.flags |= GIT_BLOB_FILTER_NO_SYSTEM_ATTRIBUTES; opts.flags |= GIT_BLOB_FILTER_ATTRIBUTES_FROM_COMMIT; - cl_git_pass(git_oid_fromstr(&opts.attr_commit_id, "b8986fec0f7bde90f78ac72706e782d82f24f2f0")); + cl_git_pass(git_oid__fromstr(&opts.attr_commit_id, "b8986fec0f7bde90f78ac72706e782d82f24f2f0", GIT_OID_SHA1)); cl_git_pass(git_revparse_single( (git_object **)&blob, g_repo, "055c872")); /* ident */ @@ -165,7 +165,7 @@ void test_filter_bare__from_specific_commit_with_no_attributes_file(void) opts.flags |= GIT_BLOB_FILTER_NO_SYSTEM_ATTRIBUTES; opts.flags |= GIT_BLOB_FILTER_ATTRIBUTES_FROM_COMMIT; - cl_git_pass(git_oid_fromstr(&opts.attr_commit_id, "5afb6a14a864e30787857dd92af837e8cdd2cb1b")); + cl_git_pass(git_oid__fromstr(&opts.attr_commit_id, "5afb6a14a864e30787857dd92af837e8cdd2cb1b", GIT_OID_SHA1)); cl_git_pass(git_revparse_single( (git_object **)&blob, g_repo, "799770d")); /* all-lf */ diff --git a/tests/libgit2/graph/ahead_behind.c b/tests/libgit2/graph/ahead_behind.c index 77d7768af..dd828c5f3 100644 --- a/tests/libgit2/graph/ahead_behind.c +++ b/tests/libgit2/graph/ahead_behind.c @@ -10,7 +10,7 @@ void test_graph_ahead_behind__initialize(void) git_oid oid; cl_git_pass(git_repository_open(&_repo, cl_fixture("testrepo.git"))); - cl_git_pass(git_oid_fromstr(&oid, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644")); + cl_git_pass(git_oid__fromstr(&oid, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644", GIT_OID_SHA1)); cl_git_pass(git_commit_lookup(&commit, _repo, &oid)); } @@ -29,8 +29,8 @@ void test_graph_ahead_behind__returns_correct_result(void) git_oid oid2; git_commit *other; - cl_git_pass(git_oid_fromstr(&oid, "e90810b8df3e80c413d903f631643c716887138d")); - cl_git_pass(git_oid_fromstr(&oid2, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644")); + cl_git_pass(git_oid__fromstr(&oid, "e90810b8df3e80c413d903f631643c716887138d", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&oid2, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644", GIT_OID_SHA1)); cl_git_pass(git_graph_ahead_behind(&ahead, &behind, _repo, &oid, &oid2)); cl_assert_equal_sz(2, ahead); diff --git a/tests/libgit2/graph/commitgraph.c b/tests/libgit2/graph/commitgraph.c index 7607c35a3..82f7f936f 100644 --- a/tests/libgit2/graph/commitgraph.c +++ b/tests/libgit2/graph/commitgraph.c @@ -19,28 +19,28 @@ void test_graph_commitgraph__parse(void) cl_git_pass(git_commit_graph_file_open(&file, git_str_cstr(&commit_graph_path))); cl_assert_equal_i(git_commit_graph_file_needs_refresh(file, git_str_cstr(&commit_graph_path)), 0); - cl_git_pass(git_oid_fromstr(&id, "5001298e0c09ad9c34e4249bc5801c75e9754fa5")); - cl_git_pass(git_commit_graph_entry_find(&e, file, &id, GIT_OID_HEXSZ)); + cl_git_pass(git_oid__fromstr(&id, "5001298e0c09ad9c34e4249bc5801c75e9754fa5", GIT_OID_SHA1)); + cl_git_pass(git_commit_graph_entry_find(&e, file, &id, GIT_OID_SHA1_HEXSIZE)); cl_assert_equal_oid(&e.sha1, &id); - cl_git_pass(git_oid_fromstr(&id, "418382dff1ffb8bdfba833f4d8bbcde58b1e7f47")); + cl_git_pass(git_oid__fromstr(&id, "418382dff1ffb8bdfba833f4d8bbcde58b1e7f47", GIT_OID_SHA1)); cl_assert_equal_oid(&e.tree_oid, &id); cl_assert_equal_i(e.generation, 1); cl_assert_equal_i(e.commit_time, UINT64_C(1273610423)); cl_assert_equal_i(e.parent_count, 0); - cl_git_pass(git_oid_fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644")); - cl_git_pass(git_commit_graph_entry_find(&e, file, &id, GIT_OID_HEXSZ)); + cl_git_pass(git_oid__fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644", GIT_OID_SHA1)); + cl_git_pass(git_commit_graph_entry_find(&e, file, &id, GIT_OID_SHA1_HEXSIZE)); cl_assert_equal_oid(&e.sha1, &id); cl_assert_equal_i(e.generation, 5); cl_assert_equal_i(e.commit_time, UINT64_C(1274813907)); cl_assert_equal_i(e.parent_count, 2); - cl_git_pass(git_oid_fromstr(&id, "9fd738e8f7967c078dceed8190330fc8648ee56a")); + cl_git_pass(git_oid__fromstr(&id, "9fd738e8f7967c078dceed8190330fc8648ee56a", GIT_OID_SHA1)); cl_git_pass(git_commit_graph_entry_parent(&parent, file, &e, 0)); cl_assert_equal_oid(&parent.sha1, &id); cl_assert_equal_i(parent.generation, 4); - cl_git_pass(git_oid_fromstr(&id, "c47800c7266a2be04c571c04d5a6614691ea99bd")); + cl_git_pass(git_oid__fromstr(&id, "c47800c7266a2be04c571c04d5a6614691ea99bd", GIT_OID_SHA1)); cl_git_pass(git_commit_graph_entry_parent(&parent, file, &e, 1)); cl_assert_equal_oid(&parent.sha1, &id); cl_assert_equal_i(parent.generation, 3); @@ -62,26 +62,26 @@ void test_graph_commitgraph__parse_octopus_merge(void) cl_git_pass(git_str_joinpath(&commit_graph_path, git_repository_path(repo), "objects/info/commit-graph")); cl_git_pass(git_commit_graph_file_open(&file, git_str_cstr(&commit_graph_path))); - cl_git_pass(git_oid_fromstr(&id, "d71c24b3b113fd1d1909998c5bfe33b86a65ee03")); - cl_git_pass(git_commit_graph_entry_find(&e, file, &id, GIT_OID_HEXSZ)); + cl_git_pass(git_oid__fromstr(&id, "d71c24b3b113fd1d1909998c5bfe33b86a65ee03", GIT_OID_SHA1)); + cl_git_pass(git_commit_graph_entry_find(&e, file, &id, GIT_OID_SHA1_HEXSIZE)); cl_assert_equal_oid(&e.sha1, &id); - cl_git_pass(git_oid_fromstr(&id, "348f16ffaeb73f319a75cec5b16a0a47d2d5e27c")); + cl_git_pass(git_oid__fromstr(&id, "348f16ffaeb73f319a75cec5b16a0a47d2d5e27c", GIT_OID_SHA1)); cl_assert_equal_oid(&e.tree_oid, &id); cl_assert_equal_i(e.generation, 7); cl_assert_equal_i(e.commit_time, UINT64_C(1447083009)); cl_assert_equal_i(e.parent_count, 3); - cl_git_pass(git_oid_fromstr(&id, "ad2ace9e15f66b3d1138922e6ffdc3ea3f967fa6")); + cl_git_pass(git_oid__fromstr(&id, "ad2ace9e15f66b3d1138922e6ffdc3ea3f967fa6", GIT_OID_SHA1)); cl_git_pass(git_commit_graph_entry_parent(&parent, file, &e, 0)); cl_assert_equal_oid(&parent.sha1, &id); cl_assert_equal_i(parent.generation, 6); - cl_git_pass(git_oid_fromstr(&id, "483065df53c0f4a02cdc6b2910b05d388fc17ffb")); + cl_git_pass(git_oid__fromstr(&id, "483065df53c0f4a02cdc6b2910b05d388fc17ffb", GIT_OID_SHA1)); cl_git_pass(git_commit_graph_entry_parent(&parent, file, &e, 1)); cl_assert_equal_oid(&parent.sha1, &id); cl_assert_equal_i(parent.generation, 2); - cl_git_pass(git_oid_fromstr(&id, "815b5a1c80ca749d705c7aa0cb294a00cbedd340")); + cl_git_pass(git_oid__fromstr(&id, "815b5a1c80ca749d705c7aa0cb294a00cbedd340", GIT_OID_SHA1)); cl_git_pass(git_commit_graph_entry_parent(&parent, file, &e, 2)); cl_assert_equal_oid(&parent.sha1, &id); cl_assert_equal_i(parent.generation, 6); @@ -124,3 +124,44 @@ void test_graph_commitgraph__writer(void) git_commit_graph_writer_free(w); git_repository_free(repo); } + +void test_graph_commitgraph__validate(void) +{ + git_repository *repo; + struct git_commit_graph *cgraph; + git_str objects_dir = GIT_STR_INIT; + + cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git"))); + cl_git_pass(git_str_joinpath(&objects_dir, git_repository_path(repo), "objects")); + + /* git_commit_graph_open() calls git_commit_graph_validate() */ + cl_git_pass(git_commit_graph_open(&cgraph, git_str_cstr(&objects_dir))); + + git_commit_graph_free(cgraph); + git_str_dispose(&objects_dir); + git_repository_free(repo); +} + +void test_graph_commitgraph__validate_corrupt(void) +{ + git_repository *repo; + struct git_commit_graph *cgraph; + int fd = -1; + + cl_fixture_sandbox("testrepo.git"); + cl_git_pass(git_repository_open(&repo, cl_git_sandbox_path(1, "testrepo.git", NULL))); + + /* corrupt commit graph checksum at the end of the file */ + cl_assert((fd = p_open(cl_git_sandbox_path(0, "testrepo.git", "objects", "info", "commit-graph", NULL), O_WRONLY)) > 0); + cl_assert(p_lseek(fd, -5, SEEK_END) > 0); + cl_must_pass(p_write(fd, "\0\0", 2)); + cl_must_pass(p_close(fd)); + + /* git_commit_graph_open() calls git_commit_graph_validate() */ + cl_git_fail(git_commit_graph_open(&cgraph, cl_git_sandbox_path(1, "testrepo.git", "objects", NULL))); + + git_commit_graph_free(cgraph); + git_repository_free(repo); + + cl_fixture_cleanup("testrepo.git"); +} diff --git a/tests/libgit2/graph/descendant_of.c b/tests/libgit2/graph/descendant_of.c index 8e9952a09..b6dffae06 100644 --- a/tests/libgit2/graph/descendant_of.c +++ b/tests/libgit2/graph/descendant_of.c @@ -9,7 +9,7 @@ void test_graph_descendant_of__initialize(void) cl_git_pass(git_repository_open(&_repo, cl_fixture("testrepo.git"))); - git_oid_fromstr(&oid, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"); + git_oid__fromstr(&oid, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, _repo, &oid)); } @@ -50,6 +50,6 @@ void test_graph_descendant_of__nopath(void) { git_oid oid; - git_oid_fromstr(&oid, "e90810b8df3e80c413d903f631643c716887138d"); + git_oid__fromstr(&oid, "e90810b8df3e80c413d903f631643c716887138d", GIT_OID_SHA1); cl_assert_equal_i(0, git_graph_descendant_of(_repo, git_commit_id(commit), &oid)); } diff --git a/tests/libgit2/graph/reachable_from_any.c b/tests/libgit2/graph/reachable_from_any.c index 9693d7d67..8e1c23874 100644 --- a/tests/libgit2/graph/reachable_from_any.c +++ b/tests/libgit2/graph/reachable_from_any.c @@ -17,7 +17,7 @@ void test_graph_reachable_from_any__initialize(void) repo = cl_git_sandbox_init(TEST_REPO_PATH); - git_oid_fromstr(&oid, "539bd011c4822c560c1d17cab095006b7a10f707"); + git_oid__fromstr(&oid, "539bd011c4822c560c1d17cab095006b7a10f707", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &oid)); cl_git_pass(git_reset(repo, (git_object *)commit, GIT_RESET_HARD, NULL)); git_commit_free(commit); diff --git a/tests/libgit2/ignore/path.c b/tests/libgit2/ignore/path.c index a574d1d79..17f28bc5d 100644 --- a/tests/libgit2/ignore/path.c +++ b/tests/libgit2/ignore/path.c @@ -286,14 +286,16 @@ void test_ignore_path__subdirectory_gitignore(void) void test_ignore_path__expand_tilde_to_homedir(void) { + git_str homefile = GIT_STR_INIT; git_config *cfg; assert_is_ignored(false, "example.global_with_tilde"); - cl_fake_home(); + cl_fake_homedir(&homefile); + cl_git_pass(git_str_joinpath(&homefile, homefile.ptr, "globalexclude")); /* construct fake home with fake global excludes */ - cl_git_mkfile("home/globalexclude", "# found me\n*.global_with_tilde\n"); + cl_git_mkfile(homefile.ptr, "# found me\n*.global_with_tilde\n"); cl_git_pass(git_repository_config(&cfg, g_repo)); cl_git_pass(git_config_set_string(cfg, "core.excludesfile", "~/globalexclude")); @@ -305,11 +307,13 @@ void test_ignore_path__expand_tilde_to_homedir(void) cl_git_pass(git_futils_rmdir_r("home", NULL, GIT_RMDIR_REMOVE_FILES)); - cl_fake_home_cleanup(NULL); + cl_fake_homedir_cleanup(NULL); git_attr_cache_flush(g_repo); /* must reset to pick up change */ assert_is_ignored(false, "example.global_with_tilde"); + + git_str_dispose(&homefile); } /* Ensure that the .gitignore in the subdirectory only affects diff --git a/tests/libgit2/ignore/status.c b/tests/libgit2/ignore/status.c index deb717590..a007774d7 100644 --- a/tests/libgit2/ignore/status.c +++ b/tests/libgit2/ignore/status.c @@ -363,6 +363,7 @@ void test_ignore_status__subdirectories_not_at_root(void) void test_ignore_status__leading_slash_ignores(void) { + git_str homedir = GIT_STR_INIT; git_status_options opts = GIT_STATUS_OPTIONS_INIT; status_entry_counts counts; static const char *paths_2[] = { @@ -385,8 +386,9 @@ void test_ignore_status__leading_slash_ignores(void) make_test_data(test_repo_1, test_files_1); - cl_fake_home(); - cl_git_mkfile("home/.gitignore", "/ignore_me\n"); + cl_fake_homedir(&homedir); + cl_git_pass(git_str_joinpath(&homedir, homedir.ptr, ".gitignore")); + cl_git_mkfile(homedir.ptr, "/ignore_me\n"); { git_config *cfg; cl_git_pass(git_repository_config(&cfg, g_repo)); @@ -412,6 +414,8 @@ void test_ignore_status__leading_slash_ignores(void) cl_assert_equal_i(counts.expected_entry_count, counts.entry_count); cl_assert_equal_i(0, counts.wrong_status_flags_count); cl_assert_equal_i(0, counts.wrong_sorted_path); + + git_str_dispose(&homedir); } void test_ignore_status__multiple_leading_slash(void) diff --git a/tests/libgit2/index/add.c b/tests/libgit2/index/add.c index f101ea266..b0c3bd2b7 100644 --- a/tests/libgit2/index/add.c +++ b/tests/libgit2/index/add.c @@ -28,7 +28,7 @@ static void test_add_entry( { git_index_entry entry = {{0}}; - cl_git_pass(git_oid_fromstr(&entry.id, idstr)); + cl_git_pass(git_oid__fromstr(&entry.id, idstr, GIT_OID_SHA1)); entry.path = mode == GIT_FILEMODE_TREE ? "test_folder" : "test_file"; entry.mode = mode; diff --git a/tests/libgit2/index/addall.c b/tests/libgit2/index/addall.c index 6f95f6386..e76b6e81d 100644 --- a/tests/libgit2/index/addall.c +++ b/tests/libgit2/index/addall.c @@ -441,6 +441,52 @@ void test_index_addall__callback_filtering(void) git_index_free(index); } +void test_index_addall__handles_ignored_files_in_directory(void) +{ + git_index *index; + + g_repo = cl_git_sandbox_init_new(TEST_DIR); + + cl_git_mkfile(TEST_DIR "/file.foo", "a file"); + cl_git_mkfile(TEST_DIR "/file.bar", "another file"); + cl_must_pass(p_mkdir(TEST_DIR "/folder", 0777)); + cl_git_mkfile(TEST_DIR "/folder/asdf", "yet another file"); + + cl_git_mkfile(TEST_DIR "/.gitignore", "folder/\n"); + + check_status(g_repo, 0, 0, 0, 3, 0, 0, 1, 0); + + cl_git_pass(git_repository_index(&index, g_repo)); + cl_git_pass(git_index_add_all(index, NULL, 0, NULL, NULL)); + + check_status(g_repo, 3, 0, 0, 0, 0, 0, 1, 0); + + git_index_free(index); +} + +void test_index_addall__force_adds_ignored_directories(void) +{ + git_index *index; + + g_repo = cl_git_sandbox_init_new(TEST_DIR); + + cl_git_mkfile(TEST_DIR "/file.foo", "a file"); + cl_git_mkfile(TEST_DIR "/file.bar", "another file"); + cl_must_pass(p_mkdir(TEST_DIR "/folder", 0777)); + cl_git_mkfile(TEST_DIR "/folder/asdf", "yet another file"); + + cl_git_mkfile(TEST_DIR "/.gitignore", "folder/\n"); + + check_status(g_repo, 0, 0, 0, 3, 0, 0, 1, 0); + + cl_git_pass(git_repository_index(&index, g_repo)); + cl_git_pass(git_index_add_all(index, NULL, GIT_INDEX_ADD_FORCE, NULL, NULL)); + + check_status(g_repo, 4, 0, 0, 0, 0, 0, 0, 0); + + git_index_free(index); +} + void test_index_addall__adds_conflicts(void) { git_index *index; diff --git a/tests/libgit2/index/bypath.c b/tests/libgit2/index/bypath.c index b32a0a789..15c11af5f 100644 --- a/tests/libgit2/index/bypath.c +++ b/tests/libgit2/index/bypath.c @@ -131,7 +131,7 @@ void test_index_bypath__add_honors_existing_case_2(void) clar__skip(); dummy.mode = GIT_FILEMODE_BLOB; - cl_git_pass(git_oid_fromstr(&dummy.id, "f990a25a74d1a8281ce2ab018ea8df66795cd60b")); + cl_git_pass(git_oid__fromstr(&dummy.id, "f990a25a74d1a8281ce2ab018ea8df66795cd60b", GIT_OID_SHA1)); /* note that `git_index_add` does no checking to canonical directories */ dummy.path = "Just_a_dir/file0.txt"; @@ -187,7 +187,7 @@ void test_index_bypath__add_honors_existing_case_3(void) clar__skip(); dummy.mode = GIT_FILEMODE_BLOB; - cl_git_pass(git_oid_fromstr(&dummy.id, "f990a25a74d1a8281ce2ab018ea8df66795cd60b")); + cl_git_pass(git_oid__fromstr(&dummy.id, "f990a25a74d1a8281ce2ab018ea8df66795cd60b", GIT_OID_SHA1)); dummy.path = "just_a_dir/filea.txt"; cl_git_pass(git_index_add(g_idx, &dummy)); @@ -218,7 +218,7 @@ void test_index_bypath__add_honors_existing_case_4(void) clar__skip(); dummy.mode = GIT_FILEMODE_BLOB; - cl_git_pass(git_oid_fromstr(&dummy.id, "f990a25a74d1a8281ce2ab018ea8df66795cd60b")); + cl_git_pass(git_oid__fromstr(&dummy.id, "f990a25a74d1a8281ce2ab018ea8df66795cd60b", GIT_OID_SHA1)); dummy.path = "just_a_dir/a/b/c/d/e/file1.txt"; cl_git_pass(git_index_add(g_idx, &dummy)); diff --git a/tests/libgit2/index/cache.c b/tests/libgit2/index/cache.c index 56885aff7..7576331b0 100644 --- a/tests/libgit2/index/cache.c +++ b/tests/libgit2/index/cache.c @@ -26,7 +26,7 @@ void test_index_cache__write_extension_at_root(void) cl_git_pass(git_index_open(&index, index_file)); cl_assert(index->tree == NULL); - cl_git_pass(git_oid_fromstr(&id, tree_id_str)); + cl_git_pass(git_oid__fromstr(&id, tree_id_str, GIT_OID_SHA1)); cl_git_pass(git_tree_lookup(&tree, g_repo, &id)); cl_git_pass(git_index_read_tree(index, tree)); git_tree_free(tree); @@ -58,7 +58,7 @@ void test_index_cache__write_extension_invalidated_root(void) cl_git_pass(git_index_open(&index, index_file)); cl_assert(index->tree == NULL); - cl_git_pass(git_oid_fromstr(&id, tree_id_str)); + cl_git_pass(git_oid__fromstr(&id, tree_id_str, GIT_OID_SHA1)); cl_git_pass(git_tree_lookup(&tree, g_repo, &id)); cl_git_pass(git_index_read_tree(index, tree)); git_tree_free(tree); @@ -98,7 +98,7 @@ void test_index_cache__read_tree_no_children(void) cl_git_pass(git_index_new(&index)); cl_assert(index->tree == NULL); - cl_git_pass(git_oid_fromstr(&id, "45dd856fdd4d89b884c340ba0e047752d9b085d6")); + cl_git_pass(git_oid__fromstr(&id, "45dd856fdd4d89b884c340ba0e047752d9b085d6", GIT_OID_SHA1)); cl_git_pass(git_tree_lookup(&tree, g_repo, &id)); cl_git_pass(git_index_read_tree(index, tree)); git_tree_free(tree); @@ -111,7 +111,7 @@ void test_index_cache__read_tree_no_children(void) memset(&entry, 0x0, sizeof(git_index_entry)); entry.path = "new.txt"; entry.mode = GIT_FILEMODE_BLOB; - git_oid_fromstr(&entry.id, "d4bcc68acd4410bf836a39f20afb2c2ece09584e"); + git_oid__fromstr(&entry.id, "d4bcc68acd4410bf836a39f20afb2c2ece09584e", GIT_OID_SHA1); cl_git_pass(git_index_add(index, &entry)); cl_assert_equal_i(-1, index->tree->entry_count); @@ -132,7 +132,7 @@ void test_index_cache__two_levels(void) memset(&entry, 0x0, sizeof(entry)); entry.mode = GIT_FILEMODE_BLOB; - cl_git_pass(git_oid_fromstr(&entry.id, "a8233120f6ad708f843d861ce2b7228ec4e3dec6")); + cl_git_pass(git_oid__fromstr(&entry.id, "a8233120f6ad708f843d861ce2b7228ec4e3dec6", GIT_OID_SHA1)); entry.path = "top-level.txt"; cl_git_pass(git_index_add(index, &entry)); @@ -156,7 +156,7 @@ void test_index_cache__two_levels(void) cl_assert(git_tree_cache_get(index->tree, "subdir")); entry.path = "top-level.txt"; - cl_git_pass(git_oid_fromstr(&entry.id, "3697d64be941a53d4ae8f6a271e4e3fa56b022cc")); + cl_git_pass(git_oid__fromstr(&entry.id, "3697d64be941a53d4ae8f6a271e4e3fa56b022cc", GIT_OID_SHA1)); cl_git_pass(git_index_add(index, &entry)); /* writ out the index after we invalidate the root */ @@ -191,7 +191,7 @@ void test_index_cache__read_tree_children(void) memset(&entry, 0x0, sizeof(git_index_entry)); entry.path = "top-level"; entry.mode = GIT_FILEMODE_BLOB; - git_oid_fromstr(&entry.id, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf"); + git_oid__fromstr(&entry.id, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf", GIT_OID_SHA1); cl_git_pass(git_index_add(index, &entry)); @@ -217,7 +217,7 @@ void test_index_cache__read_tree_children(void) /* override with a slightly different id, also dummy */ entry.path = "subdir/some-file"; - git_oid_fromstr(&entry.id, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf"); + git_oid__fromstr(&entry.id, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf", GIT_OID_SHA1); cl_git_pass(git_index_add(index, &entry)); cl_assert_equal_i(-1, index->tree->entry_count); diff --git a/tests/libgit2/index/conflicts.c b/tests/libgit2/index/conflicts.c index 41d0e219c..353886f7b 100644 --- a/tests/libgit2/index/conflicts.c +++ b/tests/libgit2/index/conflicts.c @@ -37,17 +37,17 @@ void test_index_conflicts__add(void) ancestor_entry.path = "test-one.txt"; ancestor_entry.mode = 0100644; GIT_INDEX_ENTRY_STAGE_SET(&ancestor_entry, 1); - git_oid_fromstr(&ancestor_entry.id, CONFLICTS_ONE_ANCESTOR_OID); + git_oid__fromstr(&ancestor_entry.id, CONFLICTS_ONE_ANCESTOR_OID, GIT_OID_SHA1); our_entry.path = "test-one.txt"; our_entry.mode = 0100644; GIT_INDEX_ENTRY_STAGE_SET(&our_entry, 2); - git_oid_fromstr(&our_entry.id, CONFLICTS_ONE_OUR_OID); + git_oid__fromstr(&our_entry.id, CONFLICTS_ONE_OUR_OID, GIT_OID_SHA1); their_entry.path = "test-one.txt"; their_entry.mode = 0100644; GIT_INDEX_ENTRY_STAGE_SET(&ancestor_entry, 2); - git_oid_fromstr(&their_entry.id, CONFLICTS_ONE_THEIR_OID); + git_oid__fromstr(&their_entry.id, CONFLICTS_ONE_THEIR_OID, GIT_OID_SHA1); cl_git_pass(git_index_conflict_add(repo_index, &ancestor_entry, &our_entry, &their_entry)); @@ -68,17 +68,17 @@ void test_index_conflicts__add_fixes_incorrect_stage(void) ancestor_entry.path = "test-one.txt"; ancestor_entry.mode = 0100644; GIT_INDEX_ENTRY_STAGE_SET(&ancestor_entry, 3); - git_oid_fromstr(&ancestor_entry.id, CONFLICTS_ONE_ANCESTOR_OID); + git_oid__fromstr(&ancestor_entry.id, CONFLICTS_ONE_ANCESTOR_OID, GIT_OID_SHA1); our_entry.path = "test-one.txt"; our_entry.mode = 0100644; GIT_INDEX_ENTRY_STAGE_SET(&our_entry, 1); - git_oid_fromstr(&our_entry.id, CONFLICTS_ONE_OUR_OID); + git_oid__fromstr(&our_entry.id, CONFLICTS_ONE_OUR_OID, GIT_OID_SHA1); their_entry.path = "test-one.txt"; their_entry.mode = 0100644; GIT_INDEX_ENTRY_STAGE_SET(&their_entry, 2); - git_oid_fromstr(&their_entry.id, CONFLICTS_ONE_THEIR_OID); + git_oid__fromstr(&their_entry.id, CONFLICTS_ONE_THEIR_OID, GIT_OID_SHA1); cl_git_pass(git_index_conflict_add(repo_index, &ancestor_entry, &our_entry, &their_entry)); @@ -111,17 +111,17 @@ void test_index_conflicts__add_detects_invalid_filemode(void) ancestor_entry.path = "test-one.txt"; ancestor_entry.mode = 0100644; GIT_INDEX_ENTRY_STAGE_SET(&ancestor_entry, 3); - git_oid_fromstr(&ancestor_entry.id, CONFLICTS_ONE_ANCESTOR_OID); + git_oid__fromstr(&ancestor_entry.id, CONFLICTS_ONE_ANCESTOR_OID, GIT_OID_SHA1); our_entry.path = "test-one.txt"; our_entry.mode = 0100644; GIT_INDEX_ENTRY_STAGE_SET(&our_entry, 1); - git_oid_fromstr(&our_entry.id, CONFLICTS_ONE_OUR_OID); + git_oid__fromstr(&our_entry.id, CONFLICTS_ONE_OUR_OID, GIT_OID_SHA1); their_entry.path = "test-one.txt"; their_entry.mode = 0100644; GIT_INDEX_ENTRY_STAGE_SET(&their_entry, 2); - git_oid_fromstr(&their_entry.id, CONFLICTS_ONE_THEIR_OID); + git_oid__fromstr(&their_entry.id, CONFLICTS_ONE_THEIR_OID, GIT_OID_SHA1); /* Corrupt the conflict entry's mode */ conflict_entry[i]->mode = 027431745; @@ -151,17 +151,17 @@ void test_index_conflicts__add_removes_stage_zero(void) ancestor_entry.path = "test-one.txt"; ancestor_entry.mode = 0100644; GIT_INDEX_ENTRY_STAGE_SET(&ancestor_entry, 3); - git_oid_fromstr(&ancestor_entry.id, CONFLICTS_ONE_ANCESTOR_OID); + git_oid__fromstr(&ancestor_entry.id, CONFLICTS_ONE_ANCESTOR_OID, GIT_OID_SHA1); our_entry.path = "test-one.txt"; our_entry.mode = 0100644; GIT_INDEX_ENTRY_STAGE_SET(&our_entry, 1); - git_oid_fromstr(&our_entry.id, CONFLICTS_ONE_OUR_OID); + git_oid__fromstr(&our_entry.id, CONFLICTS_ONE_OUR_OID, GIT_OID_SHA1); their_entry.path = "test-one.txt"; their_entry.mode = 0100644; GIT_INDEX_ENTRY_STAGE_SET(&their_entry, 2); - git_oid_fromstr(&their_entry.id, CONFLICTS_ONE_THEIR_OID); + git_oid__fromstr(&their_entry.id, CONFLICTS_ONE_THEIR_OID, GIT_OID_SHA1); cl_git_pass(git_index_conflict_add(repo_index, &ancestor_entry, &our_entry, &their_entry)); @@ -189,13 +189,13 @@ void test_index_conflicts__get(void) cl_assert_equal_s("conflicts-one.txt", conflict_entry[0]->path); - git_oid_fromstr(&oid, CONFLICTS_ONE_ANCESTOR_OID); + git_oid__fromstr(&oid, CONFLICTS_ONE_ANCESTOR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&oid, &conflict_entry[0]->id); - git_oid_fromstr(&oid, CONFLICTS_ONE_OUR_OID); + git_oid__fromstr(&oid, CONFLICTS_ONE_OUR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&oid, &conflict_entry[1]->id); - git_oid_fromstr(&oid, CONFLICTS_ONE_THEIR_OID); + git_oid__fromstr(&oid, CONFLICTS_ONE_THEIR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&oid, &conflict_entry[2]->id); cl_git_pass(git_index_conflict_get(&conflict_entry[0], &conflict_entry[1], @@ -203,13 +203,13 @@ void test_index_conflicts__get(void) cl_assert_equal_s("conflicts-two.txt", conflict_entry[0]->path); - git_oid_fromstr(&oid, CONFLICTS_TWO_ANCESTOR_OID); + git_oid__fromstr(&oid, CONFLICTS_TWO_ANCESTOR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&oid, &conflict_entry[0]->id); - git_oid_fromstr(&oid, CONFLICTS_TWO_OUR_OID); + git_oid__fromstr(&oid, CONFLICTS_TWO_OUR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&oid, &conflict_entry[1]->id); - git_oid_fromstr(&oid, CONFLICTS_TWO_THEIR_OID); + git_oid__fromstr(&oid, CONFLICTS_TWO_THEIR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&oid, &conflict_entry[2]->id); } @@ -223,29 +223,29 @@ void test_index_conflicts__iterate(void) cl_git_pass(git_index_conflict_next(&conflict_entry[0], &conflict_entry[1], &conflict_entry[2], iterator)); - git_oid_fromstr(&oid, CONFLICTS_ONE_ANCESTOR_OID); + git_oid__fromstr(&oid, CONFLICTS_ONE_ANCESTOR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&oid, &conflict_entry[0]->id); cl_assert(git__strcmp(conflict_entry[0]->path, "conflicts-one.txt") == 0); - git_oid_fromstr(&oid, CONFLICTS_ONE_OUR_OID); + git_oid__fromstr(&oid, CONFLICTS_ONE_OUR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&oid, &conflict_entry[1]->id); cl_assert(git__strcmp(conflict_entry[0]->path, "conflicts-one.txt") == 0); - git_oid_fromstr(&oid, CONFLICTS_ONE_THEIR_OID); + git_oid__fromstr(&oid, CONFLICTS_ONE_THEIR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&oid, &conflict_entry[2]->id); cl_assert(git__strcmp(conflict_entry[0]->path, "conflicts-one.txt") == 0); cl_git_pass(git_index_conflict_next(&conflict_entry[0], &conflict_entry[1], &conflict_entry[2], iterator)); - git_oid_fromstr(&oid, CONFLICTS_TWO_ANCESTOR_OID); + git_oid__fromstr(&oid, CONFLICTS_TWO_ANCESTOR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&oid, &conflict_entry[0]->id); cl_assert(git__strcmp(conflict_entry[0]->path, "conflicts-two.txt") == 0); - git_oid_fromstr(&oid, CONFLICTS_TWO_OUR_OID); + git_oid__fromstr(&oid, CONFLICTS_TWO_OUR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&oid, &conflict_entry[1]->id); cl_assert(git__strcmp(conflict_entry[0]->path, "conflicts-two.txt") == 0); - git_oid_fromstr(&oid, CONFLICTS_TWO_THEIR_OID); + git_oid__fromstr(&oid, CONFLICTS_TWO_THEIR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&oid, &conflict_entry[2]->id); cl_assert(git__strcmp(conflict_entry[0]->path, "conflicts-two.txt") == 0); @@ -357,7 +357,7 @@ void test_index_conflicts__partial(void) ancestor_entry.path = "test-one.txt"; ancestor_entry.mode = 0100644; GIT_INDEX_ENTRY_STAGE_SET(&ancestor_entry, 1); - git_oid_fromstr(&ancestor_entry.id, CONFLICTS_ONE_ANCESTOR_OID); + git_oid__fromstr(&ancestor_entry.id, CONFLICTS_ONE_ANCESTOR_OID, GIT_OID_SHA1); cl_git_pass(git_index_conflict_add(repo_index, &ancestor_entry, NULL, NULL)); cl_assert(git_index_entrycount(repo_index) == 9); @@ -387,17 +387,17 @@ void test_index_conflicts__case_matters(void) ancestor_entry.path = upper_case; GIT_INDEX_ENTRY_STAGE_SET(&ancestor_entry, GIT_INDEX_STAGE_ANCESTOR); - git_oid_fromstr(&ancestor_entry.id, CONFLICTS_ONE_ANCESTOR_OID); + git_oid__fromstr(&ancestor_entry.id, CONFLICTS_ONE_ANCESTOR_OID, GIT_OID_SHA1); ancestor_entry.mode = GIT_FILEMODE_BLOB; our_entry.path = upper_case; GIT_INDEX_ENTRY_STAGE_SET(&our_entry, GIT_INDEX_STAGE_OURS); - git_oid_fromstr(&our_entry.id, CONFLICTS_ONE_OUR_OID); + git_oid__fromstr(&our_entry.id, CONFLICTS_ONE_OUR_OID, GIT_OID_SHA1); our_entry.mode = GIT_FILEMODE_BLOB; their_entry.path = upper_case; GIT_INDEX_ENTRY_STAGE_SET(&their_entry, GIT_INDEX_STAGE_THEIRS); - git_oid_fromstr(&their_entry.id, CONFLICTS_ONE_THEIR_OID); + git_oid__fromstr(&their_entry.id, CONFLICTS_ONE_THEIR_OID, GIT_OID_SHA1); their_entry.mode = GIT_FILEMODE_BLOB; cl_git_pass(git_index_conflict_add(repo_index, @@ -405,17 +405,17 @@ void test_index_conflicts__case_matters(void) ancestor_entry.path = mixed_case; GIT_INDEX_ENTRY_STAGE_SET(&ancestor_entry, GIT_INDEX_STAGE_ANCESTOR); - git_oid_fromstr(&ancestor_entry.id, CONFLICTS_TWO_ANCESTOR_OID); + git_oid__fromstr(&ancestor_entry.id, CONFLICTS_TWO_ANCESTOR_OID, GIT_OID_SHA1); ancestor_entry.mode = GIT_FILEMODE_BLOB; our_entry.path = mixed_case; GIT_INDEX_ENTRY_STAGE_SET(&ancestor_entry, GIT_INDEX_STAGE_ANCESTOR); - git_oid_fromstr(&our_entry.id, CONFLICTS_TWO_OUR_OID); + git_oid__fromstr(&our_entry.id, CONFLICTS_TWO_OUR_OID, GIT_OID_SHA1); ancestor_entry.mode = GIT_FILEMODE_BLOB; their_entry.path = mixed_case; GIT_INDEX_ENTRY_STAGE_SET(&their_entry, GIT_INDEX_STAGE_THEIRS); - git_oid_fromstr(&their_entry.id, CONFLICTS_TWO_THEIR_OID); + git_oid__fromstr(&their_entry.id, CONFLICTS_TWO_THEIR_OID, GIT_OID_SHA1); their_entry.mode = GIT_FILEMODE_BLOB; cl_git_pass(git_index_conflict_add(repo_index, @@ -434,29 +434,29 @@ void test_index_conflicts__case_matters(void) correct_case = upper_case; cl_assert_equal_s(correct_case, conflict_entry[0]->path); - git_oid_fromstr(&oid, ignorecase ? CONFLICTS_TWO_ANCESTOR_OID : CONFLICTS_ONE_ANCESTOR_OID); + git_oid__fromstr(&oid, ignorecase ? CONFLICTS_TWO_ANCESTOR_OID : CONFLICTS_ONE_ANCESTOR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&oid, &conflict_entry[0]->id); cl_assert_equal_s(correct_case, conflict_entry[1]->path); - git_oid_fromstr(&oid, ignorecase ? CONFLICTS_TWO_OUR_OID : CONFLICTS_ONE_OUR_OID); + git_oid__fromstr(&oid, ignorecase ? CONFLICTS_TWO_OUR_OID : CONFLICTS_ONE_OUR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&oid, &conflict_entry[1]->id); cl_assert_equal_s(correct_case, conflict_entry[2]->path); - git_oid_fromstr(&oid, ignorecase ? CONFLICTS_TWO_THEIR_OID : CONFLICTS_ONE_THEIR_OID); + git_oid__fromstr(&oid, ignorecase ? CONFLICTS_TWO_THEIR_OID : CONFLICTS_ONE_THEIR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&oid, &conflict_entry[2]->id); cl_git_pass(git_index_conflict_get(&conflict_entry[0], &conflict_entry[1], &conflict_entry[2], repo_index, mixed_case)); cl_assert_equal_s(mixed_case, conflict_entry[0]->path); - git_oid_fromstr(&oid, CONFLICTS_TWO_ANCESTOR_OID); + git_oid__fromstr(&oid, CONFLICTS_TWO_ANCESTOR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&oid, &conflict_entry[0]->id); cl_assert_equal_s(mixed_case, conflict_entry[1]->path); - git_oid_fromstr(&oid, CONFLICTS_TWO_OUR_OID); + git_oid__fromstr(&oid, CONFLICTS_TWO_OUR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&oid, &conflict_entry[1]->id); cl_assert_equal_s(mixed_case, conflict_entry[2]->path); - git_oid_fromstr(&oid, CONFLICTS_TWO_THEIR_OID); + git_oid__fromstr(&oid, CONFLICTS_TWO_THEIR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&oid, &conflict_entry[2]->id); } diff --git a/tests/libgit2/index/crlf.c b/tests/libgit2/index/crlf.c index 7520c23a3..666ac1a0c 100644 --- a/tests/libgit2/index/crlf.c +++ b/tests/libgit2/index/crlf.c @@ -243,8 +243,9 @@ void test_index_crlf__autocrlf_false_no_attrs(void) cl_git_pass(git_index_add_bypath(g_index, "newfile.txt")); entry = git_index_get_bypath(g_index, "newfile.txt", 0); - cl_git_pass(git_oid_fromstr(&oid, - (GIT_EOL_NATIVE == GIT_EOL_CRLF) ? FILE_OID_CRLF : FILE_OID_LF)); + cl_git_pass(git_oid__fromstr(&oid, + (GIT_EOL_NATIVE == GIT_EOL_CRLF) ? FILE_OID_CRLF : FILE_OID_LF, + GIT_OID_SHA1)); cl_assert_equal_oid(&oid, &entry->id); } @@ -261,7 +262,7 @@ void test_index_crlf__autocrlf_true_no_attrs(void) cl_git_pass(git_index_add_bypath(g_index, "newfile.txt")); entry = git_index_get_bypath(g_index, "newfile.txt", 0); - cl_git_pass(git_oid_fromstr(&oid, FILE_OID_LF)); + cl_git_pass(git_oid__fromstr(&oid, FILE_OID_LF, GIT_OID_SHA1)); cl_assert_equal_oid(&oid, &entry->id); } @@ -278,7 +279,7 @@ void test_index_crlf__autocrlf_input_no_attrs(void) cl_git_pass(git_index_add_bypath(g_index, "newfile.txt")); entry = git_index_get_bypath(g_index, "newfile.txt", 0); - cl_git_pass(git_oid_fromstr(&oid, FILE_OID_LF)); + cl_git_pass(git_oid__fromstr(&oid, FILE_OID_LF, GIT_OID_SHA1)); cl_assert_equal_oid(&oid, &entry->id); } @@ -297,7 +298,7 @@ void test_index_crlf__autocrlf_false_text_auto_attr(void) cl_git_pass(git_index_add_bypath(g_index, "newfile.txt")); entry = git_index_get_bypath(g_index, "newfile.txt", 0); - cl_git_pass(git_oid_fromstr(&oid, FILE_OID_LF)); + cl_git_pass(git_oid__fromstr(&oid, FILE_OID_LF, GIT_OID_SHA1)); cl_assert_equal_oid(&oid, &entry->id); } @@ -316,7 +317,7 @@ void test_index_crlf__autocrlf_true_text_auto_attr(void) cl_git_pass(git_index_add_bypath(g_index, "newfile.txt")); entry = git_index_get_bypath(g_index, "newfile.txt", 0); - cl_git_pass(git_oid_fromstr(&oid, FILE_OID_LF)); + cl_git_pass(git_oid__fromstr(&oid, FILE_OID_LF, GIT_OID_SHA1)); cl_assert_equal_oid(&oid, &entry->id); } @@ -335,7 +336,7 @@ void test_index_crlf__autocrlf_input_text_auto_attr(void) cl_git_pass(git_index_add_bypath(g_index, "newfile.txt")); entry = git_index_get_bypath(g_index, "newfile.txt", 0); - cl_git_pass(git_oid_fromstr(&oid, FILE_OID_LF)); + cl_git_pass(git_oid__fromstr(&oid, FILE_OID_LF, GIT_OID_SHA1)); cl_assert_equal_oid(&oid, &entry->id); } @@ -355,7 +356,7 @@ void test_index_crlf__safecrlf_true_autocrlf_input_text_auto_attr(void) entry = git_index_get_bypath(g_index, "newfile.txt", 0); cl_assert(entry); - cl_git_pass(git_oid_fromstr(&oid, FILE_OID_LF)); + cl_git_pass(git_oid__fromstr(&oid, FILE_OID_LF, GIT_OID_SHA1)); cl_assert_equal_oid(&oid, &entry->id); cl_git_mkfile("./crlf/newfile2.txt", FILE_CONTENTS_CRLF); @@ -376,7 +377,7 @@ void test_index_crlf__safecrlf_true_autocrlf_input_text__no_attr(void) entry = git_index_get_bypath(g_index, "newfile.txt", 0); cl_assert(entry); - cl_git_pass(git_oid_fromstr(&oid, FILE_OID_LF)); + cl_git_pass(git_oid__fromstr(&oid, FILE_OID_LF, GIT_OID_SHA1)); cl_assert_equal_oid(&oid, &entry->id); cl_git_mkfile("./crlf/newfile2.txt", FILE_CONTENTS_CRLF); diff --git a/tests/libgit2/index/names.c b/tests/libgit2/index/names.c index 369318b03..2a41100aa 100644 --- a/tests/libgit2/index/names.c +++ b/tests/libgit2/index/names.c @@ -42,21 +42,21 @@ static void index_add_conflicts(void) entry.path = conflict[0]; entry.mode = GIT_FILEMODE_BLOB; GIT_INDEX_ENTRY_STAGE_SET(&entry, GIT_INDEX_STAGE_ANCESTOR); - git_oid_fromstr(&entry.id, "1f85ca51b8e0aac893a621b61a9c2661d6aa6d81"); + git_oid__fromstr(&entry.id, "1f85ca51b8e0aac893a621b61a9c2661d6aa6d81", GIT_OID_SHA1); cl_git_pass(git_index_add(repo_index, &entry)); /* ours */ entry.path = conflict[1]; entry.mode = GIT_FILEMODE_BLOB; GIT_INDEX_ENTRY_STAGE_SET(&entry, GIT_INDEX_STAGE_OURS); - git_oid_fromstr(&entry.id, "1f85ca51b8e0aac893a621b61a9c2661d6aa6d81"); + git_oid__fromstr(&entry.id, "1f85ca51b8e0aac893a621b61a9c2661d6aa6d81", GIT_OID_SHA1); cl_git_pass(git_index_add(repo_index, &entry)); /* theirs */ entry.path = conflict[2]; entry.mode = GIT_FILEMODE_BLOB; GIT_INDEX_ENTRY_STAGE_SET(&entry, GIT_INDEX_STAGE_THEIRS); - git_oid_fromstr(&entry.id, "1f85ca51b8e0aac893a621b61a9c2661d6aa6d81"); + git_oid__fromstr(&entry.id, "1f85ca51b8e0aac893a621b61a9c2661d6aa6d81", GIT_OID_SHA1); cl_git_pass(git_index_add(repo_index, &entry)); } } diff --git a/tests/libgit2/index/read_index.c b/tests/libgit2/index/read_index.c index 836c12b0e..ac03cf177 100644 --- a/tests/libgit2/index/read_index.c +++ b/tests/libgit2/index/read_index.c @@ -49,7 +49,7 @@ void test_index_read_index__maintains_stat_cache(void) /* add a new entry that will not have stat data */ memset(&new_entry, 0, sizeof(git_index_entry)); new_entry.path = "Hello"; - git_oid_fromstr(&new_entry.id, "0123456789012345678901234567890123456789"); + git_oid__fromstr(&new_entry.id, "0123456789012345678901234567890123456789", GIT_OID_SHA1); new_entry.file_size = 1234; new_entry.mode = 0100644; cl_git_pass(git_index_add(new_index, &new_entry)); @@ -79,7 +79,7 @@ static bool roundtrip_with_read_index(const char *tree_idstr) git_tree *tree; git_index *tree_index; - cl_git_pass(git_oid_fromstr(&tree_id, tree_idstr)); + cl_git_pass(git_oid__fromstr(&tree_id, tree_idstr, GIT_OID_SHA1)); cl_git_pass(git_tree_lookup(&tree, _repo, &tree_id)); cl_git_pass(git_index_new(&tree_index)); cl_git_pass(git_index_read_tree(tree_index, tree)); @@ -111,7 +111,7 @@ void test_index_read_index__read_and_writes(void) git_tree *tree; git_index *tree_index, *new_index; - cl_git_pass(git_oid_fromstr(&tree_id, "ae90f12eea699729ed24555e40b9fd669da12a12")); + cl_git_pass(git_oid__fromstr(&tree_id, "ae90f12eea699729ed24555e40b9fd669da12a12", GIT_OID_SHA1)); cl_git_pass(git_tree_lookup(&tree, _repo, &tree_id)); cl_git_pass(git_index_new(&tree_index)); cl_git_pass(git_index_read_tree(tree_index, tree)); @@ -148,17 +148,17 @@ static void add_conflicts(git_index *index, const char *filename) ancestor_entry.path = filename; ancestor_entry.mode = 0100644; GIT_INDEX_ENTRY_STAGE_SET(&ancestor_entry, 1); - git_oid_fromstr(&ancestor_entry.id, ancestor_ids[conflict_idx]); + git_oid__fromstr(&ancestor_entry.id, ancestor_ids[conflict_idx], GIT_OID_SHA1); our_entry.path = filename; our_entry.mode = 0100644; GIT_INDEX_ENTRY_STAGE_SET(&our_entry, 2); - git_oid_fromstr(&our_entry.id, our_ids[conflict_idx]); + git_oid__fromstr(&our_entry.id, our_ids[conflict_idx], GIT_OID_SHA1); their_entry.path = filename; their_entry.mode = 0100644; GIT_INDEX_ENTRY_STAGE_SET(&ancestor_entry, 2); - git_oid_fromstr(&their_entry.id, their_ids[conflict_idx]); + git_oid__fromstr(&their_entry.id, their_ids[conflict_idx], GIT_OID_SHA1); cl_git_pass(git_index_conflict_add(index, &ancestor_entry, &our_entry, &their_entry)); @@ -172,7 +172,7 @@ void test_index_read_index__handles_conflicts(void) git_index_conflict_iterator *conflict_iterator; const git_index_entry *ancestor, *ours, *theirs; - cl_git_pass(git_oid_fromstr(&tree_id, "ae90f12eea699729ed24555e40b9fd669da12a12")); + cl_git_pass(git_oid__fromstr(&tree_id, "ae90f12eea699729ed24555e40b9fd669da12a12", GIT_OID_SHA1)); cl_git_pass(git_tree_lookup(&tree, _repo, &tree_id)); cl_git_pass(git_index_new(&index)); cl_git_pass(git_index_new(&new_index)); diff --git a/tests/libgit2/index/rename.c b/tests/libgit2/index/rename.c index 86eaf0053..9b132cb61 100644 --- a/tests/libgit2/index/rename.c +++ b/tests/libgit2/index/rename.c @@ -22,7 +22,7 @@ void test_index_rename__single_file(void) cl_git_pass(git_index_add_bypath(index, "lame.name.txt")); cl_assert(git_index_entrycount(index) == 1); - cl_git_pass(git_oid_fromstr(&expected, "d4fa8600b4f37d7516bef4816ae2c64dbf029e3a")); + cl_git_pass(git_oid__fromstr(&expected, "d4fa8600b4f37d7516bef4816ae2c64dbf029e3a", GIT_OID_SHA1)); cl_assert(!git_index_find(&position, index, "lame.name.txt")); diff --git a/tests/libgit2/index/reuc.c b/tests/libgit2/index/reuc.c index 1f95c4136..7d8766c57 100644 --- a/tests/libgit2/index/reuc.c +++ b/tests/libgit2/index/reuc.c @@ -38,9 +38,9 @@ void test_index_reuc__add(void) git_oid ancestor_oid, our_oid, their_oid; const git_index_reuc_entry *reuc; - git_oid_fromstr(&ancestor_oid, ONE_ANCESTOR_OID); - git_oid_fromstr(&our_oid, ONE_OUR_OID); - git_oid_fromstr(&their_oid, ONE_THEIR_OID); + git_oid__fromstr(&ancestor_oid, ONE_ANCESTOR_OID, GIT_OID_SHA1); + git_oid__fromstr(&our_oid, ONE_OUR_OID, GIT_OID_SHA1); + git_oid__fromstr(&their_oid, ONE_THEIR_OID, GIT_OID_SHA1); cl_git_pass(git_index_reuc_add(repo_index, "newfile.txt", 0100644, &ancestor_oid, @@ -66,8 +66,8 @@ void test_index_reuc__add_no_ancestor(void) const git_index_reuc_entry *reuc; memset(&ancestor_oid, 0x0, sizeof(git_oid)); - git_oid_fromstr(&our_oid, ONE_OUR_OID); - git_oid_fromstr(&their_oid, ONE_THEIR_OID); + git_oid__fromstr(&our_oid, ONE_OUR_OID, GIT_OID_SHA1); + git_oid__fromstr(&their_oid, ONE_THEIR_OID, GIT_OID_SHA1); cl_git_pass(git_index_reuc_add(repo_index, "newfile.txt", 0, NULL, @@ -100,11 +100,11 @@ void test_index_reuc__read_bypath(void) cl_assert(reuc->mode[0] == 0100644); cl_assert(reuc->mode[1] == 0100644); cl_assert(reuc->mode[2] == 0100644); - git_oid_fromstr(&oid, TWO_ANCESTOR_OID); + git_oid__fromstr(&oid, TWO_ANCESTOR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&reuc->oid[0], &oid); - git_oid_fromstr(&oid, TWO_OUR_OID); + git_oid__fromstr(&oid, TWO_OUR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&reuc->oid[1], &oid); - git_oid_fromstr(&oid, TWO_THEIR_OID); + git_oid__fromstr(&oid, TWO_THEIR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&reuc->oid[2], &oid); cl_assert(reuc = git_index_reuc_get_bypath(repo_index, "one.txt")); @@ -113,11 +113,11 @@ void test_index_reuc__read_bypath(void) cl_assert(reuc->mode[0] == 0100644); cl_assert(reuc->mode[1] == 0100644); cl_assert(reuc->mode[2] == 0100644); - git_oid_fromstr(&oid, ONE_ANCESTOR_OID); + git_oid__fromstr(&oid, ONE_ANCESTOR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&reuc->oid[0], &oid); - git_oid_fromstr(&oid, ONE_OUR_OID); + git_oid__fromstr(&oid, ONE_OUR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&reuc->oid[1], &oid); - git_oid_fromstr(&oid, ONE_THEIR_OID); + git_oid__fromstr(&oid, ONE_THEIR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&reuc->oid[2], &oid); } @@ -145,11 +145,11 @@ void test_index_reuc__ignore_case(void) cl_assert(reuc->mode[0] == 0100644); cl_assert(reuc->mode[1] == 0100644); cl_assert(reuc->mode[2] == 0100644); - git_oid_fromstr(&oid, TWO_ANCESTOR_OID); + git_oid__fromstr(&oid, TWO_ANCESTOR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&reuc->oid[0], &oid); - git_oid_fromstr(&oid, TWO_OUR_OID); + git_oid__fromstr(&oid, TWO_OUR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&reuc->oid[1], &oid); - git_oid_fromstr(&oid, TWO_THEIR_OID); + git_oid__fromstr(&oid, TWO_THEIR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&reuc->oid[2], &oid); } @@ -166,11 +166,11 @@ void test_index_reuc__read_byindex(void) cl_assert(reuc->mode[0] == 0100644); cl_assert(reuc->mode[1] == 0100644); cl_assert(reuc->mode[2] == 0100644); - git_oid_fromstr(&oid, ONE_ANCESTOR_OID); + git_oid__fromstr(&oid, ONE_ANCESTOR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&reuc->oid[0], &oid); - git_oid_fromstr(&oid, ONE_OUR_OID); + git_oid__fromstr(&oid, ONE_OUR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&reuc->oid[1], &oid); - git_oid_fromstr(&oid, ONE_THEIR_OID); + git_oid__fromstr(&oid, ONE_THEIR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&reuc->oid[2], &oid); cl_assert(reuc = git_index_reuc_get_byindex(repo_index, 1)); @@ -179,11 +179,11 @@ void test_index_reuc__read_byindex(void) cl_assert(reuc->mode[0] == 0100644); cl_assert(reuc->mode[1] == 0100644); cl_assert(reuc->mode[2] == 0100644); - git_oid_fromstr(&oid, TWO_ANCESTOR_OID); + git_oid__fromstr(&oid, TWO_ANCESTOR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&reuc->oid[0], &oid); - git_oid_fromstr(&oid, TWO_OUR_OID); + git_oid__fromstr(&oid, TWO_OUR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&reuc->oid[1], &oid); - git_oid_fromstr(&oid, TWO_THEIR_OID); + git_oid__fromstr(&oid, TWO_THEIR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&reuc->oid[2], &oid); } @@ -200,9 +200,9 @@ void test_index_reuc__updates_existing(void) index_caps |= GIT_INDEX_CAPABILITY_IGNORE_CASE; cl_git_pass(git_index_set_caps(repo_index, index_caps)); - git_oid_fromstr(&ancestor_oid, TWO_ANCESTOR_OID); - git_oid_fromstr(&our_oid, TWO_OUR_OID); - git_oid_fromstr(&their_oid, TWO_THEIR_OID); + git_oid__fromstr(&ancestor_oid, TWO_ANCESTOR_OID, GIT_OID_SHA1); + git_oid__fromstr(&our_oid, TWO_OUR_OID, GIT_OID_SHA1); + git_oid__fromstr(&their_oid, TWO_THEIR_OID, GIT_OID_SHA1); cl_git_pass(git_index_reuc_add(repo_index, "two.txt", 0100644, &ancestor_oid, @@ -219,11 +219,11 @@ void test_index_reuc__updates_existing(void) cl_assert(reuc = git_index_reuc_get_byindex(repo_index, 0)); cl_assert_equal_s("TWO.txt", reuc->path); - git_oid_fromstr(&oid, TWO_OUR_OID); + git_oid__fromstr(&oid, TWO_OUR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&reuc->oid[0], &oid); - git_oid_fromstr(&oid, TWO_THEIR_OID); + git_oid__fromstr(&oid, TWO_THEIR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&reuc->oid[1], &oid); - git_oid_fromstr(&oid, TWO_ANCESTOR_OID); + git_oid__fromstr(&oid, TWO_ANCESTOR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&reuc->oid[2], &oid); } @@ -245,11 +245,11 @@ void test_index_reuc__remove(void) cl_assert(reuc->mode[0] == 0100644); cl_assert(reuc->mode[1] == 0100644); cl_assert(reuc->mode[2] == 0100644); - git_oid_fromstr(&oid, TWO_ANCESTOR_OID); + git_oid__fromstr(&oid, TWO_ANCESTOR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&reuc->oid[0], &oid); - git_oid_fromstr(&oid, TWO_OUR_OID); + git_oid__fromstr(&oid, TWO_OUR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&reuc->oid[1], &oid); - git_oid_fromstr(&oid, TWO_THEIR_OID); + git_oid__fromstr(&oid, TWO_THEIR_OID, GIT_OID_SHA1); cl_assert_equal_oid(&reuc->oid[2], &oid); } @@ -261,18 +261,18 @@ void test_index_reuc__write(void) git_index_clear(repo_index); /* Write out of order to ensure sorting is correct */ - git_oid_fromstr(&ancestor_oid, TWO_ANCESTOR_OID); - git_oid_fromstr(&our_oid, TWO_OUR_OID); - git_oid_fromstr(&their_oid, TWO_THEIR_OID); + git_oid__fromstr(&ancestor_oid, TWO_ANCESTOR_OID, GIT_OID_SHA1); + git_oid__fromstr(&our_oid, TWO_OUR_OID, GIT_OID_SHA1); + git_oid__fromstr(&their_oid, TWO_THEIR_OID, GIT_OID_SHA1); cl_git_pass(git_index_reuc_add(repo_index, "two.txt", 0100644, &ancestor_oid, 0100644, &our_oid, 0100644, &their_oid)); - git_oid_fromstr(&ancestor_oid, ONE_ANCESTOR_OID); - git_oid_fromstr(&our_oid, ONE_OUR_OID); - git_oid_fromstr(&their_oid, ONE_THEIR_OID); + git_oid__fromstr(&ancestor_oid, ONE_ANCESTOR_OID, GIT_OID_SHA1); + git_oid__fromstr(&our_oid, ONE_OUR_OID, GIT_OID_SHA1); + git_oid__fromstr(&their_oid, ONE_THEIR_OID, GIT_OID_SHA1); cl_git_pass(git_index_reuc_add(repo_index, "one.txt", 0100644, &ancestor_oid, diff --git a/tests/libgit2/index/tests.c b/tests/libgit2/index/tests.c index 205d12e5b..da3ff6dd7 100644 --- a/tests/libgit2/index/tests.c +++ b/tests/libgit2/index/tests.c @@ -259,7 +259,7 @@ void test_index_tests__add(void) * This has been generated by executing the following * $ echo "hey there" | git hash-object --stdin */ - cl_git_pass(git_oid_fromstr(&id1, "a8233120f6ad708f843d861ce2b7228ec4e3dec6")); + cl_git_pass(git_oid__fromstr(&id1, "a8233120f6ad708f843d861ce2b7228ec4e3dec6", GIT_OID_SHA1)); /* Add the new file to the index */ cl_git_pass(git_index_add_bypath(index, "test.txt")); @@ -304,7 +304,7 @@ void test_index_tests__add_frombuffer(void) * This has been generated by executing the following * $ echo "hey there" | git hash-object --stdin */ - cl_git_pass(git_oid_fromstr(&id1, "a8233120f6ad708f843d861ce2b7228ec4e3dec6")); + cl_git_pass(git_oid__fromstr(&id1, "a8233120f6ad708f843d861ce2b7228ec4e3dec6", GIT_OID_SHA1)); /* Add the new file to the index */ memset(&entry, 0x0, sizeof(git_index_entry)); @@ -447,7 +447,7 @@ void test_index_tests__add_frombuffer_reset_entry(void) * This has been generated by executing the following * $ echo "hey there" | git hash-object --stdin */ - cl_git_pass(git_oid_fromstr(&id1, "a8233120f6ad708f843d861ce2b7228ec4e3dec6")); + cl_git_pass(git_oid__fromstr(&id1, "a8233120f6ad708f843d861ce2b7228ec4e3dec6", GIT_OID_SHA1)); cl_git_pass(git_index_add_bypath(index, "test.txt")); @@ -511,7 +511,7 @@ void test_index_tests__add_issue_1397(void) * This has been generated by executing the following * $ git hash-object crlf_file.txt */ - cl_git_pass(git_oid_fromstr(&id1, "8312e0889a9cbab77c732b6bc39b51a683e3a318")); + cl_git_pass(git_oid__fromstr(&id1, "8312e0889a9cbab77c732b6bc39b51a683e3a318", GIT_OID_SHA1)); /* Make sure the initial SHA-1 is correct */ cl_assert((entry = git_index_get_bypath(index, "crlf_file.txt", 0)) != NULL); @@ -600,7 +600,7 @@ static void assert_add_fails(git_repository *repo, const char *fn) entry.path = fn; entry.mode = GIT_FILEMODE_BLOB; - cl_git_pass(git_oid_fromstr(&entry.id, "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391")); + cl_git_pass(git_oid__fromstr(&entry.id, "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", GIT_OID_SHA1)); cl_git_fail(git_index_add(index, &entry)); @@ -705,7 +705,7 @@ void test_index_tests__write_tree_invalid_unowned_index(void) cl_git_pass(git_index_new(&idx)); - cl_git_pass(git_oid_fromstr(&entry.id, "8312e0a89a9cbab77c732b6bc39b51a783e3a318")); + cl_git_pass(git_oid__fromstr(&entry.id, "8312e0a89a9cbab77c732b6bc39b51a783e3a318", GIT_OID_SHA1)); entry.path = "foo"; entry.mode = GIT_FILEMODE_BLOB; cl_git_pass(git_index_add(idx, &entry)); @@ -1147,12 +1147,12 @@ void test_index_tests__can_modify_while_iterating(void) * ensure that our iterator is backed by a snapshot and thus returns * the number of entries from when the iterator was created. */ - cl_git_pass(git_oid_fromstr(&new_entry.id, "8312e0a89a9cbab77c732b6bc39b51a783e3a318")); + cl_git_pass(git_oid__fromstr(&new_entry.id, "8312e0a89a9cbab77c732b6bc39b51a783e3a318", GIT_OID_SHA1)); new_entry.path = "newfile"; new_entry.mode = GIT_FILEMODE_BLOB; cl_git_pass(git_index_add(index, &new_entry)); - cl_git_pass(git_oid_fromstr(&new_entry.id, "4141414141414141414141414141414141414141")); + cl_git_pass(git_oid__fromstr(&new_entry.id, "4141414141414141414141414141414141414141", GIT_OID_SHA1)); new_entry.path = "Makefile"; new_entry.mode = GIT_FILEMODE_BLOB; cl_git_pass(git_index_add(index, &new_entry)); diff --git a/tests/libgit2/iterator/index.c b/tests/libgit2/iterator/index.c index 7218b4f75..a0083479d 100644 --- a/tests/libgit2/iterator/index.c +++ b/tests/libgit2/iterator/index.c @@ -52,7 +52,7 @@ static void index_iterator_test( if (expected_oids != NULL) { git_oid oid; - cl_git_pass(git_oid_fromstr(&oid, expected_oids[count])); + cl_git_pass(git_oid__fromstr(&oid, expected_oids[count], GIT_OID_SHA1)); cl_assert_equal_oid(&oid, &entry->id); } @@ -999,7 +999,7 @@ static void create_paths(git_index *index, const char *root, int depth) memset(&entry, 0, sizeof(git_index_entry)); entry.path = fullpath.ptr; entry.mode = GIT_FILEMODE_BLOB; - git_oid_fromstr(&entry.id, "d44e18fb93b7107b5cd1b95d601591d77869a1b6"); + git_oid__fromstr(&entry.id, "d44e18fb93b7107b5cd1b95d601591d77869a1b6", GIT_OID_SHA1); cl_git_pass(git_index_add(index, &entry)); } else if (depth > 0) { @@ -1296,17 +1296,17 @@ static void add_conflict( ancestor.path = ancestor_path; ancestor.mode = GIT_FILEMODE_BLOB; - git_oid_fromstr(&ancestor.id, "d44e18fb93b7107b5cd1b95d601591d77869a1b6"); + git_oid__fromstr(&ancestor.id, "d44e18fb93b7107b5cd1b95d601591d77869a1b6", GIT_OID_SHA1); GIT_INDEX_ENTRY_STAGE_SET(&ancestor, 1); ours.path = our_path; ours.mode = GIT_FILEMODE_BLOB; - git_oid_fromstr(&ours.id, "d44e18fb93b7107b5cd1b95d601591d77869a1b6"); + git_oid__fromstr(&ours.id, "d44e18fb93b7107b5cd1b95d601591d77869a1b6", GIT_OID_SHA1); GIT_INDEX_ENTRY_STAGE_SET(&ours, 2); theirs.path = their_path; theirs.mode = GIT_FILEMODE_BLOB; - git_oid_fromstr(&theirs.id, "d44e18fb93b7107b5cd1b95d601591d77869a1b6"); + git_oid__fromstr(&theirs.id, "d44e18fb93b7107b5cd1b95d601591d77869a1b6", GIT_OID_SHA1); GIT_INDEX_ENTRY_STAGE_SET(&theirs, 3); cl_git_pass(git_index_conflict_add(index, &ancestor, &ours, &theirs)); diff --git a/tests/libgit2/iterator/tree.c b/tests/libgit2/iterator/tree.c index 06a920a18..7dfee28be 100644 --- a/tests/libgit2/iterator/tree.c +++ b/tests/libgit2/iterator/tree.c @@ -675,7 +675,7 @@ void test_iterator_tree__case_conflicts_0(void) g_repo = cl_git_sandbox_init("icase"); - cl_git_pass(git_oid_fromstr(&blob_id, blob_sha)); /* lookup blob */ + cl_git_pass(git_oid__fromstr(&blob_id, blob_sha, GIT_OID_SHA1)); /* lookup blob */ /* create tree with: A/1.file, A/3.file, a/2.file, a/4.file */ build_test_tree( @@ -729,7 +729,7 @@ void test_iterator_tree__case_conflicts_1(void) g_repo = cl_git_sandbox_init("icase"); - cl_git_pass(git_oid_fromstr(&blob_id, blob_sha)); /* lookup blob */ + cl_git_pass(git_oid__fromstr(&blob_id, blob_sha, GIT_OID_SHA1)); /* lookup blob */ /* create: A/a A/b/1 A/c a/a a/b a/C */ build_test_tree(&Ab_id, g_repo, "b|1|", &blob_id); @@ -798,7 +798,7 @@ void test_iterator_tree__case_conflicts_2(void) g_repo = cl_git_sandbox_init("icase"); - cl_git_pass(git_oid_fromstr(&blob_id, blob_sha)); /* lookup blob */ + cl_git_pass(git_oid__fromstr(&blob_id, blob_sha, GIT_OID_SHA1)); /* lookup blob */ build_test_tree(&d1, g_repo, "b|16|,b|foo|", &blob_id, &blob_id); build_test_tree(&d2, g_repo, "b|15|,b|FOO|", &blob_id, &blob_id); diff --git a/tests/libgit2/iterator/workdir.c b/tests/libgit2/iterator/workdir.c index 86b847cab..7634997e1 100644 --- a/tests/libgit2/iterator/workdir.c +++ b/tests/libgit2/iterator/workdir.c @@ -1481,7 +1481,7 @@ void test_iterator_workdir__hash_when_requested(void) git_iterator *iter; const git_index_entry *entry; git_iterator_options iter_opts = GIT_ITERATOR_OPTIONS_INIT; - git_oid expected_id = {{0}}; + git_oid expected_id = GIT_OID_SHA1_ZERO; size_t i; struct merge_index_entry expected[] = { @@ -1514,7 +1514,7 @@ void test_iterator_workdir__hash_when_requested(void) for (i = 0; i < sizeof(expected) / sizeof(struct merge_index_entry); i++) { cl_git_pass(git_iterator_advance(&entry, iter)); - cl_git_pass(git_oid_fromstr(&expected_id, expected[i].oid_str)); + cl_git_pass(git_oid__fromstr(&expected_id, expected[i].oid_str, GIT_OID_SHA1)); cl_assert_equal_oid(&expected_id, &entry->id); cl_assert_equal_s(expected[i].path, entry->path); } diff --git a/tests/libgit2/merge/driver.c b/tests/libgit2/merge/driver.c index b7d320cbb..fd73c3770 100644 --- a/tests/libgit2/merge/driver.c +++ b/tests/libgit2/merge/driver.c @@ -22,7 +22,7 @@ void test_merge_driver__initialize(void) repo = cl_git_sandbox_init(TEST_REPO_PATH); git_repository_index(&repo_index, repo); - git_oid_fromstr(&automergeable_id, AUTOMERGEABLE_IDSTR); + git_oid__fromstr(&automergeable_id, AUTOMERGEABLE_IDSTR, GIT_OID_SHA1); /* Ensure that the user's merge.conflictstyle doesn't interfere */ cl_git_pass(git_repository_config(&cfg, repo)); @@ -145,7 +145,7 @@ static void merge_branch(void) git_oid their_id; git_annotated_commit *their_head; - cl_git_pass(git_oid_fromstr(&their_id, BRANCH_ID)); + cl_git_pass(git_oid__fromstr(&their_id, BRANCH_ID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&their_head, repo, &their_id)); cl_git_pass(git_merge(repo, (const git_annotated_commit **)&their_head, @@ -299,7 +299,7 @@ void test_merge_driver__default_can_be_specified(void) merge_opts.default_driver = "custom"; - cl_git_pass(git_oid_fromstr(&their_id, BRANCH_ID)); + cl_git_pass(git_oid__fromstr(&their_id, BRANCH_ID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&their_head, repo, &their_id)); cl_git_pass(git_merge(repo, (const git_annotated_commit **)&their_head, diff --git a/tests/libgit2/merge/files.c b/tests/libgit2/merge/files.c index 6296f3b7b..6c1c2e13f 100644 --- a/tests/libgit2/merge/files.c +++ b/tests/libgit2/merge/files.c @@ -149,15 +149,15 @@ void test_merge_files__automerge_from_index(void) git_merge_file_result result = {0}; git_index_entry ancestor, ours, theirs; - git_oid_fromstr(&ancestor.id, "6212c31dab5e482247d7977e4f0dd3601decf13b"); + git_oid__fromstr(&ancestor.id, "6212c31dab5e482247d7977e4f0dd3601decf13b", GIT_OID_SHA1); ancestor.path = "automergeable.txt"; ancestor.mode = 0100644; - git_oid_fromstr(&ours.id, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf"); + git_oid__fromstr(&ours.id, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf", GIT_OID_SHA1); ours.path = "automergeable.txt"; ours.mode = 0100755; - git_oid_fromstr(&theirs.id, "058541fc37114bfc1dddf6bd6bffc7fae5c2e6fe"); + git_oid__fromstr(&theirs.id, "058541fc37114bfc1dddf6bd6bffc7fae5c2e6fe", GIT_OID_SHA1); theirs.path = "newname.txt"; theirs.mode = 0100644; diff --git a/tests/libgit2/merge/merge_helpers.c b/tests/libgit2/merge/merge_helpers.c index ce3cd229b..1406987e5 100644 --- a/tests/libgit2/merge/merge_helpers.c +++ b/tests/libgit2/merge/merge_helpers.c @@ -165,7 +165,7 @@ static int index_entry_eq_merge_index_entry(const struct merge_index_entry *expe bool test_oid; if (strlen(expected->oid_str) != 0) { - cl_git_pass(git_oid_fromstr(&expected_oid, expected->oid_str)); + cl_git_pass(git_oid__fromstr(&expected_oid, expected->oid_str, GIT_OID_SHA1)); test_oid = 1; } else test_oid = 0; @@ -304,21 +304,21 @@ int merge_test_reuc(git_index *index, const struct merge_reuc_entry expected[], return 0; if (expected[i].ancestor_mode > 0) { - cl_git_pass(git_oid_fromstr(&expected_oid, expected[i].ancestor_oid_str)); + cl_git_pass(git_oid__fromstr(&expected_oid, expected[i].ancestor_oid_str, GIT_OID_SHA1)); if (git_oid_cmp(&reuc_entry->oid[0], &expected_oid) != 0) return 0; } if (expected[i].our_mode > 0) { - cl_git_pass(git_oid_fromstr(&expected_oid, expected[i].our_oid_str)); + cl_git_pass(git_oid__fromstr(&expected_oid, expected[i].our_oid_str, GIT_OID_SHA1)); if (git_oid_cmp(&reuc_entry->oid[1], &expected_oid) != 0) return 0; } if (expected[i].their_mode > 0) { - cl_git_pass(git_oid_fromstr(&expected_oid, expected[i].their_oid_str)); + cl_git_pass(git_oid__fromstr(&expected_oid, expected[i].their_oid_str, GIT_OID_SHA1)); if (git_oid_cmp(&reuc_entry->oid[2], &expected_oid) != 0) return 0; @@ -353,7 +353,7 @@ int merge_test_workdir(git_repository *repo, const struct merge_index_entry expe for (i = 0; i < expected_len; i++) { git_blob_create_from_workdir(&actual_oid, repo, expected[i].path); - git_oid_fromstr(&expected_oid, expected[i].oid_str); + git_oid__fromstr(&expected_oid, expected[i].oid_str, GIT_OID_SHA1); if (git_oid_cmp(&actual_oid, &expected_oid) != 0) return 0; diff --git a/tests/libgit2/merge/merge_helpers.h b/tests/libgit2/merge/merge_helpers.h index 339812ba5..72c6e61f7 100644 --- a/tests/libgit2/merge/merge_helpers.h +++ b/tests/libgit2/merge/merge_helpers.h @@ -6,7 +6,7 @@ struct merge_index_entry { uint16_t mode; - char oid_str[GIT_OID_HEXSZ+1]; + char oid_str[GIT_OID_SHA1_HEXSIZE+1]; int stage; char path[128]; }; @@ -27,9 +27,9 @@ struct merge_reuc_entry { unsigned int ancestor_mode; unsigned int our_mode; unsigned int their_mode; - char ancestor_oid_str[GIT_OID_HEXSZ+1]; - char our_oid_str[GIT_OID_HEXSZ+1]; - char their_oid_str[GIT_OID_HEXSZ+1]; + char ancestor_oid_str[GIT_OID_SHA1_HEXSIZE+1]; + char our_oid_str[GIT_OID_SHA1_HEXSIZE+1]; + char their_oid_str[GIT_OID_SHA1_HEXSIZE+1]; }; struct merge_index_conflict_data { diff --git a/tests/libgit2/merge/trees/renames.c b/tests/libgit2/merge/trees/renames.c index 26f6d3306..a27945ee0 100644 --- a/tests/libgit2/merge/trees/renames.c +++ b/tests/libgit2/merge/trees/renames.c @@ -286,7 +286,7 @@ void test_merge_trees_renames__cache_recomputation(void) void *data; size_t i; - cl_git_pass(git_oid_fromstr(&blob, "a2d8d1824c68541cca94ffb90f79291eba495921")); + cl_git_pass(git_oid__fromstr(&blob, "a2d8d1824c68541cca94ffb90f79291eba495921", GIT_OID_SHA1)); /* * Create a 50MB blob that consists of NUL bytes only. It is important diff --git a/tests/libgit2/merge/trees/treediff.c b/tests/libgit2/merge/trees/treediff.c index cd2cf7827..094018d3c 100644 --- a/tests/libgit2/merge/trees/treediff.c +++ b/tests/libgit2/merge/trees/treediff.c @@ -61,9 +61,9 @@ static void test_find_differences( opts.metric->similarity = git_diff_find_similar__calc_similarity; opts.metric->payload = (void *)GIT_HASHSIG_SMART_WHITESPACE; - cl_git_pass(git_oid_fromstr(&ancestor_oid, ancestor_oidstr)); - cl_git_pass(git_oid_fromstr(&ours_oid, ours_oidstr)); - cl_git_pass(git_oid_fromstr(&theirs_oid, theirs_oidstr)); + cl_git_pass(git_oid__fromstr(&ancestor_oid, ancestor_oidstr, GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&ours_oid, ours_oidstr, GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&theirs_oid, theirs_oidstr, GIT_OID_SHA1)); cl_git_pass(git_tree_lookup(&ancestor_tree, repo, &ancestor_oid)); cl_git_pass(git_tree_lookup(&ours_tree, repo, &ours_oid)); diff --git a/tests/libgit2/merge/trees/trivial.c b/tests/libgit2/merge/trees/trivial.c index dce392c86..287a53cfe 100644 --- a/tests/libgit2/merge/trees/trivial.c +++ b/tests/libgit2/merge/trees/trivial.c @@ -258,7 +258,7 @@ void test_merge_trees_trivial__13(void) cl_git_pass(merge_trivial(&result, "trivial-13", "trivial-13-branch")); cl_assert(entry = git_index_get_bypath(result, "modified-in-13.txt", 0)); - cl_git_pass(git_oid_fromstr(&expected_oid, "1cff9ec6a47a537380dedfdd17c9e76d74259a2b")); + cl_git_pass(git_oid__fromstr(&expected_oid, "1cff9ec6a47a537380dedfdd17c9e76d74259a2b", GIT_OID_SHA1)); cl_assert_equal_oid(&expected_oid, &entry->id); cl_assert(git_index_reuc_entrycount(result) == 0); @@ -277,7 +277,7 @@ void test_merge_trees_trivial__14(void) cl_git_pass(merge_trivial(&result, "trivial-14", "trivial-14-branch")); cl_assert(entry = git_index_get_bypath(result, "modified-in-14-branch.txt", 0)); - cl_git_pass(git_oid_fromstr(&expected_oid, "26153a3ff3649b6c2bb652d3f06878c6e0a172f9")); + cl_git_pass(git_oid__fromstr(&expected_oid, "26153a3ff3649b6c2bb652d3f06878c6e0a172f9", GIT_OID_SHA1)); cl_assert(git_oid_cmp(&entry->id, &expected_oid) == 0); cl_assert(git_index_reuc_entrycount(result) == 0); diff --git a/tests/libgit2/merge/workdir/dirty.c b/tests/libgit2/merge/workdir/dirty.c index b9c2ad033..36b42a103 100644 --- a/tests/libgit2/merge/workdir/dirty.c +++ b/tests/libgit2/merge/workdir/dirty.c @@ -94,7 +94,7 @@ static int merge_branch(void) git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT; int error; - cl_git_pass(git_oid_fromstr(&their_oids[0], MERGE_BRANCH_OID)); + cl_git_pass(git_oid__fromstr(&their_oids[0], MERGE_BRANCH_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&their_head, repo, &their_oids[0])); checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE; diff --git a/tests/libgit2/merge/workdir/setup.c b/tests/libgit2/merge/workdir/setup.c index 3db2d074f..98ccdf700 100644 --- a/tests/libgit2/merge/workdir/setup.c +++ b/tests/libgit2/merge/workdir/setup.c @@ -78,7 +78,7 @@ void test_merge_workdir_setup__one_branch(void) git_reference *octo1_ref; git_annotated_commit *our_head, *their_heads[1]; - cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); + cl_git_pass(git_oid__fromstr(&our_oid, ORIG_HEAD, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH)); @@ -104,10 +104,10 @@ void test_merge_workdir_setup__one_oid(void) git_oid octo1_oid; git_annotated_commit *our_head, *their_heads[1]; - cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); + cl_git_pass(git_oid__fromstr(&our_oid, ORIG_HEAD, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); - cl_git_pass(git_oid_fromstr(&octo1_oid, OCTO1_OID)); + cl_git_pass(git_oid__fromstr(&octo1_oid, OCTO1_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&their_heads[0], repo, &octo1_oid)); cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 1)); @@ -129,7 +129,7 @@ void test_merge_workdir_setup__two_branches(void) git_reference *octo2_ref; git_annotated_commit *our_head, *their_heads[2]; - cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); + cl_git_pass(git_oid__fromstr(&our_oid, ORIG_HEAD, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH)); @@ -162,7 +162,7 @@ void test_merge_workdir_setup__three_branches(void) git_reference *octo3_ref; git_annotated_commit *our_head, *their_heads[3]; - cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); + cl_git_pass(git_oid__fromstr(&our_oid, ORIG_HEAD, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH)); @@ -200,16 +200,16 @@ void test_merge_workdir_setup__three_oids(void) git_oid octo3_oid; git_annotated_commit *our_head, *their_heads[3]; - cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); + cl_git_pass(git_oid__fromstr(&our_oid, ORIG_HEAD, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); - cl_git_pass(git_oid_fromstr(&octo1_oid, OCTO1_OID)); + cl_git_pass(git_oid__fromstr(&octo1_oid, OCTO1_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&their_heads[0], repo, &octo1_oid)); - cl_git_pass(git_oid_fromstr(&octo2_oid, OCTO2_OID)); + cl_git_pass(git_oid__fromstr(&octo2_oid, OCTO2_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&their_heads[1], repo, &octo2_oid)); - cl_git_pass(git_oid_fromstr(&octo3_oid, OCTO3_OID)); + cl_git_pass(git_oid__fromstr(&octo3_oid, OCTO3_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&their_heads[2], repo, &octo3_oid)); cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 3)); @@ -233,13 +233,13 @@ void test_merge_workdir_setup__branches_and_oids_1(void) git_oid octo2_oid; git_annotated_commit *our_head, *their_heads[2]; - cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); + cl_git_pass(git_oid__fromstr(&our_oid, ORIG_HEAD, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref)); - cl_git_pass(git_oid_fromstr(&octo2_oid, OCTO2_OID)); + cl_git_pass(git_oid__fromstr(&octo2_oid, OCTO2_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&their_heads[1], repo, &octo2_oid)); cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 2)); @@ -266,19 +266,19 @@ void test_merge_workdir_setup__branches_and_oids_2(void) git_oid octo4_oid; git_annotated_commit *our_head, *their_heads[4]; - cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); + cl_git_pass(git_oid__fromstr(&our_oid, ORIG_HEAD, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref)); - cl_git_pass(git_oid_fromstr(&octo2_oid, OCTO2_OID)); + cl_git_pass(git_oid__fromstr(&octo2_oid, OCTO2_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&their_heads[1], repo, &octo2_oid)); cl_git_pass(git_reference_lookup(&octo3_ref, repo, GIT_REFS_HEADS_DIR OCTO3_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[2], repo, octo3_ref)); - cl_git_pass(git_oid_fromstr(&octo4_oid, OCTO4_OID)); + cl_git_pass(git_oid__fromstr(&octo4_oid, OCTO4_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&their_heads[3], repo, &octo4_oid)); cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 4)); @@ -308,16 +308,16 @@ void test_merge_workdir_setup__branches_and_oids_3(void) git_reference *octo4_ref; git_annotated_commit *our_head, *their_heads[4]; - cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); + cl_git_pass(git_oid__fromstr(&our_oid, ORIG_HEAD, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); - cl_git_pass(git_oid_fromstr(&octo1_oid, OCTO1_OID)); + cl_git_pass(git_oid__fromstr(&octo1_oid, OCTO1_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&their_heads[0], repo, &octo1_oid)); cl_git_pass(git_reference_lookup(&octo2_ref, repo, GIT_REFS_HEADS_DIR OCTO2_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[1], repo, octo2_ref)); - cl_git_pass(git_oid_fromstr(&octo3_oid, OCTO3_OID)); + cl_git_pass(git_oid__fromstr(&octo3_oid, OCTO3_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&their_heads[2], repo, &octo3_oid)); cl_git_pass(git_reference_lookup(&octo4_ref, repo, GIT_REFS_HEADS_DIR OCTO4_BRANCH)); @@ -351,16 +351,16 @@ void test_merge_workdir_setup__branches_and_oids_4(void) git_reference *octo5_ref; git_annotated_commit *our_head, *their_heads[5]; - cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); + cl_git_pass(git_oid__fromstr(&our_oid, ORIG_HEAD, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); - cl_git_pass(git_oid_fromstr(&octo1_oid, OCTO1_OID)); + cl_git_pass(git_oid__fromstr(&octo1_oid, OCTO1_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&their_heads[0], repo, &octo1_oid)); cl_git_pass(git_reference_lookup(&octo2_ref, repo, GIT_REFS_HEADS_DIR OCTO2_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[1], repo, octo2_ref)); - cl_git_pass(git_oid_fromstr(&octo3_oid, OCTO3_OID)); + cl_git_pass(git_oid__fromstr(&octo3_oid, OCTO3_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&their_heads[2], repo, &octo3_oid)); cl_git_pass(git_reference_lookup(&octo4_ref, repo, GIT_REFS_HEADS_DIR OCTO4_BRANCH)); @@ -397,7 +397,7 @@ void test_merge_workdir_setup__three_same_branches(void) git_reference *octo1_3_ref; git_annotated_commit *our_head, *their_heads[3]; - cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); + cl_git_pass(git_oid__fromstr(&our_oid, ORIG_HEAD, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); cl_git_pass(git_reference_lookup(&octo1_1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH)); @@ -435,16 +435,16 @@ void test_merge_workdir_setup__three_same_oids(void) git_oid octo1_3_oid; git_annotated_commit *our_head, *their_heads[3]; - cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); + cl_git_pass(git_oid__fromstr(&our_oid, ORIG_HEAD, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); - cl_git_pass(git_oid_fromstr(&octo1_1_oid, OCTO1_OID)); + cl_git_pass(git_oid__fromstr(&octo1_1_oid, OCTO1_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&their_heads[0], repo, &octo1_1_oid)); - cl_git_pass(git_oid_fromstr(&octo1_2_oid, OCTO1_OID)); + cl_git_pass(git_oid__fromstr(&octo1_2_oid, OCTO1_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&their_heads[1], repo, &octo1_2_oid)); - cl_git_pass(git_oid_fromstr(&octo1_3_oid, OCTO1_OID)); + cl_git_pass(git_oid__fromstr(&octo1_3_oid, OCTO1_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&their_heads[2], repo, &octo1_3_oid)); cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 3)); @@ -512,7 +512,7 @@ void test_merge_workdir_setup__remote_tracking_one_branch(void) cl_git_pass(create_remote_tracking_branch(OCTO1_BRANCH, OCTO1_OID)); - cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); + cl_git_pass(git_oid__fromstr(&our_oid, ORIG_HEAD, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_REMOTES_DIR "origin/" OCTO1_BRANCH)); @@ -542,7 +542,7 @@ void test_merge_workdir_setup__remote_tracking_two_branches(void) cl_git_pass(create_remote_tracking_branch(OCTO1_BRANCH, OCTO1_OID)); cl_git_pass(create_remote_tracking_branch(OCTO2_BRANCH, OCTO2_OID)); - cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); + cl_git_pass(git_oid__fromstr(&our_oid, ORIG_HEAD, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_REMOTES_DIR "origin/" OCTO1_BRANCH)); @@ -579,7 +579,7 @@ void test_merge_workdir_setup__remote_tracking_three_branches(void) cl_git_pass(create_remote_tracking_branch(OCTO2_BRANCH, OCTO2_OID)); cl_git_pass(create_remote_tracking_branch(OCTO3_BRANCH, OCTO3_OID)); - cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); + cl_git_pass(git_oid__fromstr(&our_oid, ORIG_HEAD, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_REMOTES_DIR "origin/" OCTO1_BRANCH)); @@ -618,7 +618,7 @@ void test_merge_workdir_setup__normal_branch_and_remote_tracking_branch(void) cl_git_pass(create_remote_tracking_branch(OCTO2_BRANCH, OCTO2_OID)); - cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); + cl_git_pass(git_oid__fromstr(&our_oid, ORIG_HEAD, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH)); @@ -652,7 +652,7 @@ void test_merge_workdir_setup__remote_tracking_branch_and_normal_branch(void) cl_git_pass(create_remote_tracking_branch(OCTO1_BRANCH, OCTO1_OID)); - cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); + cl_git_pass(git_oid__fromstr(&our_oid, ORIG_HEAD, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_REMOTES_DIR "origin/" OCTO1_BRANCH)); @@ -689,7 +689,7 @@ void test_merge_workdir_setup__two_remote_tracking_branch_and_two_normal_branche cl_git_pass(create_remote_tracking_branch(OCTO2_BRANCH, OCTO2_OID)); cl_git_pass(create_remote_tracking_branch(OCTO4_BRANCH, OCTO4_OID)); - cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); + cl_git_pass(git_oid__fromstr(&our_oid, ORIG_HEAD, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH)); @@ -730,10 +730,10 @@ void test_merge_workdir_setup__pull_one(void) git_oid octo1_1_oid; git_annotated_commit *our_head, *their_heads[1]; - cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); + cl_git_pass(git_oid__fromstr(&our_oid, ORIG_HEAD, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); - cl_git_pass(git_oid_fromstr(&octo1_1_oid, OCTO1_OID)); + cl_git_pass(git_oid__fromstr(&octo1_1_oid, OCTO1_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_from_fetchhead(&their_heads[0], repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH, "http://remote.url/repo.git", &octo1_1_oid)); cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 1)); @@ -755,13 +755,13 @@ void test_merge_workdir_setup__pull_two(void) git_oid octo2_oid; git_annotated_commit *our_head, *their_heads[2]; - cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); + cl_git_pass(git_oid__fromstr(&our_oid, ORIG_HEAD, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); - cl_git_pass(git_oid_fromstr(&octo1_oid, OCTO1_OID)); + cl_git_pass(git_oid__fromstr(&octo1_oid, OCTO1_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_from_fetchhead(&their_heads[0], repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH, "http://remote.url/repo.git", &octo1_oid)); - cl_git_pass(git_oid_fromstr(&octo2_oid, OCTO2_OID)); + cl_git_pass(git_oid__fromstr(&octo2_oid, OCTO2_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_from_fetchhead(&their_heads[1], repo, GIT_REFS_HEADS_DIR OCTO2_BRANCH, "http://remote.url/repo.git", &octo2_oid)); cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 2)); @@ -785,16 +785,16 @@ void test_merge_workdir_setup__pull_three(void) git_oid octo3_oid; git_annotated_commit *our_head, *their_heads[3]; - cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); + cl_git_pass(git_oid__fromstr(&our_oid, ORIG_HEAD, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); - cl_git_pass(git_oid_fromstr(&octo1_oid, OCTO1_OID)); + cl_git_pass(git_oid__fromstr(&octo1_oid, OCTO1_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_from_fetchhead(&their_heads[0], repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH, "http://remote.url/repo.git", &octo1_oid)); - cl_git_pass(git_oid_fromstr(&octo2_oid, OCTO2_OID)); + cl_git_pass(git_oid__fromstr(&octo2_oid, OCTO2_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_from_fetchhead(&their_heads[1], repo, GIT_REFS_HEADS_DIR OCTO2_BRANCH, "http://remote.url/repo.git", &octo2_oid)); - cl_git_pass(git_oid_fromstr(&octo3_oid, OCTO3_OID)); + cl_git_pass(git_oid__fromstr(&octo3_oid, OCTO3_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_from_fetchhead(&their_heads[2], repo, GIT_REFS_HEADS_DIR OCTO3_BRANCH, "http://remote.url/repo.git", &octo3_oid)); cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 3)); @@ -818,16 +818,16 @@ void test_merge_workdir_setup__three_remotes(void) git_oid octo3_oid; git_annotated_commit *our_head, *their_heads[3]; - cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); + cl_git_pass(git_oid__fromstr(&our_oid, ORIG_HEAD, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); - cl_git_pass(git_oid_fromstr(&octo1_oid, OCTO1_OID)); + cl_git_pass(git_oid__fromstr(&octo1_oid, OCTO1_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_from_fetchhead(&their_heads[0], repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH, "http://remote.first/repo.git", &octo1_oid)); - cl_git_pass(git_oid_fromstr(&octo2_oid, OCTO2_OID)); + cl_git_pass(git_oid__fromstr(&octo2_oid, OCTO2_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_from_fetchhead(&their_heads[1], repo, GIT_REFS_HEADS_DIR OCTO2_BRANCH, "http://remote.second/repo.git", &octo2_oid)); - cl_git_pass(git_oid_fromstr(&octo3_oid, OCTO3_OID)); + cl_git_pass(git_oid__fromstr(&octo3_oid, OCTO3_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_from_fetchhead(&their_heads[2], repo, GIT_REFS_HEADS_DIR OCTO3_BRANCH, "http://remote.third/repo.git", &octo3_oid)); cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 3)); @@ -852,19 +852,19 @@ void test_merge_workdir_setup__two_remotes(void) git_oid octo4_oid; git_annotated_commit *our_head, *their_heads[4]; - cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); + cl_git_pass(git_oid__fromstr(&our_oid, ORIG_HEAD, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); - cl_git_pass(git_oid_fromstr(&octo1_oid, OCTO1_OID)); + cl_git_pass(git_oid__fromstr(&octo1_oid, OCTO1_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_from_fetchhead(&their_heads[0], repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH, "http://remote.first/repo.git", &octo1_oid)); - cl_git_pass(git_oid_fromstr(&octo2_oid, OCTO2_OID)); + cl_git_pass(git_oid__fromstr(&octo2_oid, OCTO2_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_from_fetchhead(&their_heads[1], repo, GIT_REFS_HEADS_DIR OCTO2_BRANCH, "http://remote.second/repo.git", &octo2_oid)); - cl_git_pass(git_oid_fromstr(&octo3_oid, OCTO3_OID)); + cl_git_pass(git_oid__fromstr(&octo3_oid, OCTO3_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_from_fetchhead(&their_heads[2], repo, GIT_REFS_HEADS_DIR OCTO3_BRANCH, "http://remote.first/repo.git", &octo3_oid)); - cl_git_pass(git_oid_fromstr(&octo4_oid, OCTO4_OID)); + cl_git_pass(git_oid__fromstr(&octo4_oid, OCTO4_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_from_fetchhead(&their_heads[3], repo, GIT_REFS_HEADS_DIR OCTO4_BRANCH, "http://remote.second/repo.git", &octo4_oid)); cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 4)); @@ -888,7 +888,7 @@ void test_merge_workdir_setup__id_from_head(void) git_reference *ref; git_annotated_commit *heads[3]; - cl_git_pass(git_oid_fromstr(&expected_id, OCTO1_OID)); + cl_git_pass(git_oid__fromstr(&expected_id, OCTO1_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_from_fetchhead(&heads[0], repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH, "http://remote.url/repo.git", &expected_id)); id = git_annotated_commit_id(heads[0]); cl_assert_equal_i(1, git_oid_equal(id, &expected_id)); @@ -920,7 +920,7 @@ static int annotated_commit_foreach_cb(const git_oid *oid, void *payload) git_oid expected_oid; struct annotated_commit_cb_data *cb_data = payload; - git_oid_fromstr(&expected_oid, cb_data->oid_str[cb_data->i]); + git_oid__fromstr(&expected_oid, cb_data->oid_str[cb_data->i], GIT_OID_SHA1); cl_assert(git_oid_cmp(&expected_oid, oid) == 0); cb_data->i++; return 0; @@ -998,7 +998,7 @@ void test_merge_workdir_setup__retained_after_success(void) git_reference *octo1_ref; git_annotated_commit *our_head, *their_heads[1]; - cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); + cl_git_pass(git_oid__fromstr(&our_oid, ORIG_HEAD, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH)); @@ -1025,7 +1025,7 @@ void test_merge_workdir_setup__removed_after_failure(void) git_reference *octo1_ref; git_annotated_commit *our_head, *their_heads[1]; - cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); + cl_git_pass(git_oid__fromstr(&our_oid, ORIG_HEAD, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH)); @@ -1052,7 +1052,7 @@ void test_merge_workdir_setup__unlocked_after_success(void) git_reference *octo1_ref; git_annotated_commit *our_head, *their_heads[1]; - cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); + cl_git_pass(git_oid__fromstr(&our_oid, ORIG_HEAD, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH)); @@ -1075,7 +1075,7 @@ void test_merge_workdir_setup__unlocked_after_conflict(void) git_reference *octo1_ref; git_annotated_commit *our_head, *their_heads[1]; - cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); + cl_git_pass(git_oid__fromstr(&our_oid, ORIG_HEAD, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH)); diff --git a/tests/libgit2/merge/workdir/simple.c b/tests/libgit2/merge/workdir/simple.c index b9d3fc24c..e9cffeea8 100644 --- a/tests/libgit2/merge/workdir/simple.c +++ b/tests/libgit2/merge/workdir/simple.c @@ -99,7 +99,7 @@ static void merge_simple_branch(int merge_file_favor, int addl_checkout_strategy git_merge_options merge_opts = GIT_MERGE_OPTIONS_INIT; git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT; - cl_git_pass(git_oid_fromstr(&their_oids[0], THEIRS_SIMPLE_OID)); + cl_git_pass(git_oid__fromstr(&their_oids[0], THEIRS_SIMPLE_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&their_heads[0], repo, &their_oids[0])); merge_opts.file_favor = merge_file_favor; @@ -180,14 +180,14 @@ void test_merge_workdir_simple__index_reload(void) cl_git_pass(git_index_read(repo_index, 0)); entry.mode = GIT_FILEMODE_BLOB; - cl_git_pass(git_oid_fromstr(&entry.id, "11deab00b2d3a6f5a3073988ac050c2d7b6655e2")); + cl_git_pass(git_oid__fromstr(&entry.id, "11deab00b2d3a6f5a3073988ac050c2d7b6655e2", GIT_OID_SHA1)); entry.path = "automergeable.txt"; cl_git_pass(git_index_add(repo_index, &entry)); cl_git_pass(git_index_add_bypath(tmp_index, "automergeable.txt")); cl_git_pass(git_index_write(tmp_index)); - cl_git_pass(git_oid_fromstr(&their_oid, THEIRS_SIMPLE_OID)); + cl_git_pass(git_oid__fromstr(&their_oid, THEIRS_SIMPLE_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&their_heads[0], repo, &their_oid)); cl_git_pass(git_merge(repo, (const git_annotated_commit **)their_heads, 1, NULL, NULL)); @@ -669,7 +669,7 @@ void test_merge_workdir_simple__directory_file(void) cl_git_pass(git_commit_lookup(&head_commit, repo, &head_commit_id)); cl_git_pass(git_reset(repo, (git_object *)head_commit, GIT_RESET_HARD, NULL)); - cl_git_pass(git_oid_fromstr(&their_oids[0], THEIRS_DIRECTORY_FILE)); + cl_git_pass(git_oid__fromstr(&their_oids[0], THEIRS_DIRECTORY_FILE, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&their_heads[0], repo, &their_oids[0])); merge_opts.file_favor = 0; @@ -700,7 +700,7 @@ void test_merge_workdir_simple__unrelated(void) { 0100644, "c8f06f2e3bb2964174677e91f0abead0e43c9e5d", 0, "unchanged.txt" }, }; - cl_git_pass(git_oid_fromstr(&their_oids[0], THEIRS_UNRELATED_PARENT)); + cl_git_pass(git_oid__fromstr(&their_oids[0], THEIRS_UNRELATED_PARENT, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&their_heads[0], repo, &their_oids[0])); merge_opts.file_favor = 0; @@ -731,7 +731,7 @@ void test_merge_workdir_simple__unrelated_with_conflicts(void) { 0100644, "c8f06f2e3bb2964174677e91f0abead0e43c9e5d", 0, "unchanged.txt" }, }; - cl_git_pass(git_oid_fromstr(&their_oids[0], THEIRS_UNRELATED_OID)); + cl_git_pass(git_oid__fromstr(&their_oids[0], THEIRS_UNRELATED_OID, GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&their_heads[0], repo, &their_oids[0])); merge_opts.file_favor = 0; @@ -755,8 +755,8 @@ void test_merge_workdir_simple__binary(void) { 0100644, "836b8b82b26cab22eaaed8820877c76d6c8bca19", 3, "binary" }, }; - cl_git_pass(git_oid_fromstr(&our_oid, "cc338e4710c9b257106b8d16d82f86458d5beaf1")); - cl_git_pass(git_oid_fromstr(&their_oid, "ad01aebfdf2ac13145efafe3f9fcf798882f1730")); + cl_git_pass(git_oid__fromstr(&our_oid, "cc338e4710c9b257106b8d16d82f86458d5beaf1", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&their_oid, "ad01aebfdf2ac13145efafe3f9fcf798882f1730", GIT_OID_SHA1)); cl_git_pass(git_commit_lookup(&our_commit, repo, &our_oid)); cl_git_pass(git_reset(repo, (git_object *)our_commit, GIT_RESET_HARD, NULL)); @@ -770,7 +770,7 @@ void test_merge_workdir_simple__binary(void) cl_git_pass(git_index_add_bypath(repo_index, "binary")); cl_assert((binary_entry = git_index_get_bypath(repo_index, "binary", 0)) != NULL); - cl_git_pass(git_oid_fromstr(&our_file_oid, "23ed141a6ae1e798b2f721afedbe947c119111ba")); + cl_git_pass(git_oid__fromstr(&our_file_oid, "23ed141a6ae1e798b2f721afedbe947c119111ba", GIT_OID_SHA1)); cl_assert(git_oid_cmp(&binary_entry->id, &our_file_oid) == 0); git_annotated_commit_free(their_head); diff --git a/tests/libgit2/merge/workdir/trivial.c b/tests/libgit2/merge/workdir/trivial.c index fe8374851..364182c89 100644 --- a/tests/libgit2/merge/workdir/trivial.c +++ b/tests/libgit2/merge/workdir/trivial.c @@ -222,7 +222,7 @@ void test_merge_workdir_trivial__13(void) cl_git_pass(merge_trivial("trivial-13", "trivial-13-branch")); cl_assert(entry = git_index_get_bypath(repo_index, "modified-in-13.txt", 0)); - cl_git_pass(git_oid_fromstr(&expected_oid, "1cff9ec6a47a537380dedfdd17c9e76d74259a2b")); + cl_git_pass(git_oid__fromstr(&expected_oid, "1cff9ec6a47a537380dedfdd17c9e76d74259a2b", GIT_OID_SHA1)); cl_assert(git_oid_cmp(&entry->id, &expected_oid) == 0); cl_assert(git_index_reuc_entrycount(repo_index) == 0); @@ -238,7 +238,7 @@ void test_merge_workdir_trivial__14(void) cl_git_pass(merge_trivial("trivial-14", "trivial-14-branch")); cl_assert(entry = git_index_get_bypath(repo_index, "modified-in-14-branch.txt", 0)); - cl_git_pass(git_oid_fromstr(&expected_oid, "26153a3ff3649b6c2bb652d3f06878c6e0a172f9")); + cl_git_pass(git_oid__fromstr(&expected_oid, "26153a3ff3649b6c2bb652d3f06878c6e0a172f9", GIT_OID_SHA1)); cl_assert(git_oid_cmp(&entry->id, &expected_oid) == 0); cl_assert(git_index_reuc_entrycount(repo_index) == 0); diff --git a/tests/libgit2/network/remote/push.c b/tests/libgit2/network/remote/push.c index 3905debdf..16588a292 100644 --- a/tests/libgit2/network/remote/push.c +++ b/tests/libgit2/network/remote/push.c @@ -1,5 +1,6 @@ #include "clar_libgit2.h" #include "git2/sys/commit.h" +#include "oid.h" static git_remote *_remote; static git_repository *_repo, *_dummy; @@ -57,7 +58,7 @@ void test_network_remote_push__delete_notification(void) expected.src_refname = ""; expected.dst_refname = "refs/heads/master"; - memset(&expected.dst, 0, sizeof(git_oid)); + git_oid_clear(&expected.dst, GIT_OID_SHA1); git_oid_cpy(&expected.src, git_reference_target(ref)); opts.callbacks.push_negotiation = negotiation_cb; @@ -102,7 +103,7 @@ void test_network_remote_push__create_notification(void) expected.src_refname = "refs/heads/empty-tree"; expected.dst_refname = "refs/heads/empty-tree"; git_oid_cpy(&expected.dst, git_reference_target(ref)); - memset(&expected.src, 0, sizeof(git_oid)); + git_oid_clear(&expected.src, GIT_OID_SHA1); opts.callbacks.push_negotiation = negotiation_cb; opts.callbacks.payload = &expected; diff --git a/tests/libgit2/network/remote/rename.c b/tests/libgit2/network/remote/rename.c index 1fd2affba..b071f9cef 100644 --- a/tests/libgit2/network/remote/rename.c +++ b/tests/libgit2/network/remote/rename.c @@ -164,13 +164,13 @@ void test_network_remote_rename__renaming_a_remote_moves_the_underlying_referenc void test_network_remote_rename__overwrite_ref_in_target(void) { git_oid id; - char idstr[GIT_OID_HEXSZ + 1] = {0}; + char idstr[GIT_OID_SHA1_HEXSIZE + 1] = {0}; git_reference *ref; git_branch_t btype; git_branch_iterator *iter; git_strarray problems = {0}; - cl_git_pass(git_oid_fromstr(&id, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750")); + cl_git_pass(git_oid__fromstr(&id, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", GIT_OID_SHA1)); cl_git_pass(git_reference_create(&ref, _repo, "refs/remotes/renamed/master", &id, 1, NULL)); git_reference_free(ref); @@ -206,7 +206,7 @@ void test_network_remote_rename__symref_head(void) git_branch_t btype; git_branch_iterator *iter; git_strarray problems = {0}; - char idstr[GIT_OID_HEXSZ + 1] = {0}; + char idstr[GIT_OID_SHA1_HEXSIZE + 1] = {0}; git_vector refs; cl_git_pass(git_reference_symbolic_create(&ref, _repo, "refs/remotes/test/HEAD", "refs/remotes/test/master", 0, NULL)); diff --git a/tests/libgit2/notes/notes.c b/tests/libgit2/notes/notes.c index a36cddb8a..06c440955 100644 --- a/tests/libgit2/notes/notes.c +++ b/tests/libgit2/notes/notes.c @@ -33,7 +33,7 @@ static void create_note(git_oid *note_oid, const char *canonical_namespace, cons { git_oid oid; - cl_git_pass(git_oid_fromstr(&oid, target_sha)); + cl_git_pass(git_oid__fromstr(&oid, target_sha, GIT_OID_SHA1)); cl_git_pass(git_note_create(note_oid, _repo, canonical_namespace, _sig, _sig, &oid, message, 0)); } @@ -60,10 +60,10 @@ static int note_list_cb( cl_assert(*count < EXPECTATIONS_COUNT); - cl_git_pass(git_oid_fromstr(&expected_note_oid, list_expectations[*count].note_sha)); + cl_git_pass(git_oid__fromstr(&expected_note_oid, list_expectations[*count].note_sha, GIT_OID_SHA1)); cl_assert_equal_oid(&expected_note_oid, blob_id); - cl_git_pass(git_oid_fromstr(&expected_target_oid, list_expectations[*count].annotated_object_sha)); + cl_git_pass(git_oid__fromstr(&expected_target_oid, list_expectations[*count].annotated_object_sha, GIT_OID_SHA1)); cl_assert_equal_oid(&expected_target_oid, annotated_obj_id); (*count)++; @@ -85,12 +85,12 @@ static int note_list_create_cb( size_t i; for (i = 0; notes[i].note_oid != NULL; i++) { - cl_git_pass(git_oid_fromstr(&expected_note_oid, notes[i].note_oid)); + cl_git_pass(git_oid__fromstr(&expected_note_oid, notes[i].note_oid, GIT_OID_SHA1)); if (git_oid_cmp(&expected_note_oid, blob_oid) != 0) continue; - cl_git_pass(git_oid_fromstr(&expected_target_oid, notes[i].object_oid)); + cl_git_pass(git_oid__fromstr(&expected_target_oid, notes[i].object_oid, GIT_OID_SHA1)); if (git_oid_cmp(&expected_target_oid, annotated_obj_id) != 0) continue; @@ -140,7 +140,7 @@ void test_notes_notes__can_create_a_note_from_commit(void) { NULL, NULL, 0 } }; - cl_git_pass(git_oid_fromstr(&oid, can_create_a_note_from_commit[0].object_oid)); + cl_git_pass(git_oid__fromstr(&oid, can_create_a_note_from_commit[0].object_oid, GIT_OID_SHA1)); cl_git_pass(git_note_commit_create(¬es_commit_out, NULL, _repo, NULL, _sig, _sig, &oid, "I decorate 4a20\n", 1)); @@ -169,11 +169,11 @@ void test_notes_notes__can_create_a_note_from_commit_given_an_existing_commit(vo { NULL, NULL, 0 } }; - cl_git_pass(git_oid_fromstr(&oid, "4a202b346bb0fb0db7eff3cffeb3c70babbd2045")); + cl_git_pass(git_oid__fromstr(&oid, "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", GIT_OID_SHA1)); cl_git_pass(git_note_commit_create(¬es_commit_out, NULL, _repo, NULL, _sig, _sig, &oid, "I decorate 4a20\n", 0)); - cl_git_pass(git_oid_fromstr(&oid, "9fd738e8f7967c078dceed8190330fc8648ee56a")); + cl_git_pass(git_oid__fromstr(&oid, "9fd738e8f7967c078dceed8190330fc8648ee56a", GIT_OID_SHA1)); git_commit_lookup(&existing_notes_commit, _repo, ¬es_commit_out); @@ -274,7 +274,7 @@ void test_notes_notes__inserting_a_note_without_passing_a_namespace_uses_the_def git_note *note, *default_namespace_note; git_buf default_ref = GIT_BUF_INIT; - cl_git_pass(git_oid_fromstr(&target_oid, "08b041783f40edfe12bb406c9c9a8a040177c125")); + cl_git_pass(git_oid__fromstr(&target_oid, "08b041783f40edfe12bb406c9c9a8a040177c125", GIT_OID_SHA1)); cl_git_pass(git_note_default_ref(&default_ref, _repo)); create_note(¬e_oid, NULL, "08b041783f40edfe12bb406c9c9a8a040177c125", "hello world\n"); @@ -295,7 +295,7 @@ void test_notes_notes__can_insert_a_note_with_a_custom_namespace(void) git_oid note_oid, target_oid; git_note *note; - cl_git_pass(git_oid_fromstr(&target_oid, "08b041783f40edfe12bb406c9c9a8a040177c125")); + cl_git_pass(git_oid__fromstr(&target_oid, "08b041783f40edfe12bb406c9c9a8a040177c125", GIT_OID_SHA1)); create_note(¬e_oid, "refs/notes/some/namespace", "08b041783f40edfe12bb406c9c9a8a040177c125", "hello world on a custom namespace\n"); @@ -315,7 +315,7 @@ void test_notes_notes__creating_a_note_on_a_target_which_already_has_one_returns int error; git_oid note_oid, target_oid; - cl_git_pass(git_oid_fromstr(&target_oid, "08b041783f40edfe12bb406c9c9a8a040177c125")); + cl_git_pass(git_oid__fromstr(&target_oid, "08b041783f40edfe12bb406c9c9a8a040177c125", GIT_OID_SHA1)); create_note(¬e_oid, NULL, "08b041783f40edfe12bb406c9c9a8a040177c125", "hello world\n"); error = git_note_create(¬e_oid, _repo, NULL, _sig, _sig, &target_oid, "hello world\n", 0); @@ -334,7 +334,7 @@ void test_notes_notes__creating_a_note_on_a_target_can_overwrite_existing_note(v git_oid note_oid, target_oid; git_note *note, *namespace_note; - cl_git_pass(git_oid_fromstr(&target_oid, "08b041783f40edfe12bb406c9c9a8a040177c125")); + cl_git_pass(git_oid__fromstr(&target_oid, "08b041783f40edfe12bb406c9c9a8a040177c125", GIT_OID_SHA1)); create_note(¬e_oid, NULL, "08b041783f40edfe12bb406c9c9a8a040177c125", "hello old world\n"); cl_git_pass(git_note_create(¬e_oid, _repo, NULL, _sig, _sig, &target_oid, "hello new world\n", 1)); @@ -381,7 +381,7 @@ void test_notes_notes__can_read_a_note(void) create_note(¬e_oid, "refs/notes/i-can-see-dead-notes", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", "I decorate 4a20\n"); - cl_git_pass(git_oid_fromstr(&target_oid, "4a202b346bb0fb0db7eff3cffeb3c70babbd2045")); + cl_git_pass(git_oid__fromstr(&target_oid, "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", GIT_OID_SHA1)); cl_git_pass(git_note_read(¬e, _repo, "refs/notes/i-can-see-dead-notes", &target_oid)); @@ -397,7 +397,7 @@ void test_notes_notes__can_read_a_note_from_a_commit(void) git_commit *notes_commit; git_note *note; - cl_git_pass(git_oid_fromstr(&oid, "4a202b346bb0fb0db7eff3cffeb3c70babbd2045")); + cl_git_pass(git_oid__fromstr(&oid, "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", GIT_OID_SHA1)); cl_git_pass(git_note_commit_create(¬es_commit_oid, NULL, _repo, NULL, _sig, _sig, &oid, "I decorate 4a20\n", 1)); cl_git_pass(git_commit_lookup(¬es_commit, _repo, ¬es_commit_oid)); cl_assert(notes_commit); @@ -416,7 +416,7 @@ void test_notes_notes__attempt_to_read_a_note_from_a_commit_with_no_note_fails(v git_commit *notes_commit; git_note *note; - cl_git_pass(git_oid_fromstr(&oid, "4a202b346bb0fb0db7eff3cffeb3c70babbd2045")); + cl_git_pass(git_oid__fromstr(&oid, "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", GIT_OID_SHA1)); cl_git_pass(git_note_commit_create(¬es_commit_oid, NULL, _repo, NULL, _sig, _sig, &oid, "I decorate 4a20\n", 1)); @@ -450,7 +450,7 @@ void test_notes_notes__can_insert_a_note_in_an_existing_fanout(void) git_oid note_oid, target_oid; git_note *_note; - cl_git_pass(git_oid_fromstr(&target_oid, "08b041783f40edfe12bb406c9c9a8a040177c125")); + cl_git_pass(git_oid__fromstr(&target_oid, "08b041783f40edfe12bb406c9c9a8a040177c125", GIT_OID_SHA1)); for (i = 0; i < MESSAGES_COUNT; i++) { cl_git_pass(git_note_create(¬e_oid, _repo, "refs/notes/fanout", _sig, _sig, &target_oid, messages[i], 0)); @@ -470,10 +470,10 @@ void test_notes_notes__can_read_a_note_in_an_existing_fanout(void) git_oid note_oid, target_oid; git_note *note; - cl_git_pass(git_oid_fromstr(&target_oid, "8496071c1b46c854b31185ea97743be6a8774479")); + cl_git_pass(git_oid__fromstr(&target_oid, "8496071c1b46c854b31185ea97743be6a8774479", GIT_OID_SHA1)); cl_git_pass(git_note_read(¬e, _repo, "refs/notes/fanout", &target_oid)); - cl_git_pass(git_oid_fromstr(¬e_oid, "08b041783f40edfe12bb406c9c9a8a040177c125")); + cl_git_pass(git_oid__fromstr(¬e_oid, "08b041783f40edfe12bb406c9c9a8a040177c125", GIT_OID_SHA1)); cl_assert_equal_oid(git_note_id(note), ¬e_oid); git_note_free(note); @@ -487,7 +487,7 @@ void test_notes_notes__can_remove_a_note(void) create_note(¬e_oid, "refs/notes/i-can-see-dead-notes", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", "I decorate 4a20\n"); - cl_git_pass(git_oid_fromstr(&target_oid, "4a202b346bb0fb0db7eff3cffeb3c70babbd2045")); + cl_git_pass(git_oid__fromstr(&target_oid, "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", GIT_OID_SHA1)); cl_git_pass(git_note_remove(_repo, "refs/notes/i-can-see-dead-notes", _sig, _sig, &target_oid)); cl_git_fail(git_note_read(¬e, _repo, "refs/notes/i-can-see-dead-notes", &target_oid)); @@ -501,7 +501,7 @@ void test_notes_notes__can_remove_a_note_from_commit(void) git_commit *existing_notes_commit; git_reference *ref; - cl_git_pass(git_oid_fromstr(&oid, "4a202b346bb0fb0db7eff3cffeb3c70babbd2045")); + cl_git_pass(git_oid__fromstr(&oid, "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", GIT_OID_SHA1)); cl_git_pass(git_note_commit_create(¬es_commit_oid, NULL, _repo, NULL, _sig, _sig, &oid, "I decorate 4a20\n", 0)); @@ -528,7 +528,7 @@ void test_notes_notes__can_remove_a_note_in_an_existing_fanout(void) git_oid target_oid; git_note *note; - cl_git_pass(git_oid_fromstr(&target_oid, "8496071c1b46c854b31185ea97743be6a8774479")); + cl_git_pass(git_oid__fromstr(&target_oid, "8496071c1b46c854b31185ea97743be6a8774479", GIT_OID_SHA1)); cl_git_pass(git_note_remove(_repo, "refs/notes/fanout", _sig, _sig, &target_oid)); cl_git_fail(git_note_read(¬e, _repo, "refs/notes/fanout", &target_oid)); @@ -539,7 +539,7 @@ void test_notes_notes__removing_a_note_which_doesnt_exists_returns_ENOTFOUND(voi int error; git_oid target_oid; - cl_git_pass(git_oid_fromstr(&target_oid, "8496071c1b46c854b31185ea97743be6a8774479")); + cl_git_pass(git_oid__fromstr(&target_oid, "8496071c1b46c854b31185ea97743be6a8774479", GIT_OID_SHA1)); cl_git_pass(git_note_remove(_repo, "refs/notes/fanout", _sig, _sig, &target_oid)); error = git_note_remove(_repo, "refs/notes/fanout", _sig, _sig, &target_oid); @@ -628,8 +628,8 @@ void test_notes_notes__iterate_from_commit(void) }; int i, err; - cl_git_pass(git_oid_fromstr(&(oids[0]), "a65fedf39aefe402d3bb6e24df4d4f5fe4547750")); - cl_git_pass(git_oid_fromstr(&(oids[1]), "c47800c7266a2be04c571c04d5a6614691ea99bd")); + cl_git_pass(git_oid__fromstr(&(oids[0]), "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&(oids[1]), "c47800c7266a2be04c571c04d5a6614691ea99bd", GIT_OID_SHA1)); cl_git_pass(git_note_commit_create(¬es_commit_oids[0], NULL, _repo, NULL, _sig, _sig, &(oids[0]), note_message[0], 0)); diff --git a/tests/libgit2/notes/notesref.c b/tests/libgit2/notes/notesref.c index 6ba324c76..8696ff66a 100644 --- a/tests/libgit2/notes/notesref.c +++ b/tests/libgit2/notes/notesref.c @@ -36,7 +36,7 @@ void test_notes_notesref__config_corenotesref(void) git_buf default_ref = GIT_BUF_INIT; cl_git_pass(git_signature_now(&_sig, "alice", "alice@example.com")); - cl_git_pass(git_oid_fromstr(&oid, "8496071c1b46c854b31185ea97743be6a8774479")); + cl_git_pass(git_oid__fromstr(&oid, "8496071c1b46c854b31185ea97743be6a8774479", GIT_OID_SHA1)); cl_git_pass(git_repository_config(&_cfg, _repo)); diff --git a/tests/libgit2/object/blob/fromstream.c b/tests/libgit2/object/blob/fromstream.c index 60ff3991b..dad0b52e1 100644 --- a/tests/libgit2/object/blob/fromstream.c +++ b/tests/libgit2/object/blob/fromstream.c @@ -23,7 +23,7 @@ void test_object_blob_fromstream__multiple_write(void) git_writestream *stream; int i, howmany = 6; - cl_git_pass(git_oid_fromstr(&expected_id, "321cbdf08803c744082332332838df6bd160f8f9")); + cl_git_pass(git_oid__fromstr(&expected_id, "321cbdf08803c744082332332838df6bd160f8f9", GIT_OID_SHA1)); cl_git_fail_with(GIT_ENOTFOUND, git_object_lookup(&blob, repo, &expected_id, GIT_OBJECT_ANY)); @@ -64,7 +64,7 @@ static void assert_named_chunked_blob(const char *expected_sha, const char *fake git_writestream *stream; int i, howmany = 6; - cl_git_pass(git_oid_fromstr(&expected_id, expected_sha)); + cl_git_pass(git_oid__fromstr(&expected_id, expected_sha, GIT_OID_SHA1)); cl_git_pass(git_blob_create_from_stream(&stream, repo, fake_name)); diff --git a/tests/libgit2/object/cache.c b/tests/libgit2/object/cache.c index 08bf03648..bf8c6fb53 100644 --- a/tests/libgit2/object/cache.c +++ b/tests/libgit2/object/cache.c @@ -91,7 +91,7 @@ void test_object_cache__cache_counts(void) for (i = 0; g_data[i].sha != NULL; ++i) { int count = (int)git_cache_size(&g_repo->objects); - cl_git_pass(git_oid_fromstr(&oid, g_data[i].sha)); + cl_git_pass(git_oid__fromstr(&oid, g_data[i].sha, GIT_OID_SHA1)); /* alternate between loading raw and parsed objects */ if ((i & 1) == 0) { @@ -118,7 +118,7 @@ void test_object_cache__cache_counts(void) for (i = 0; g_data[i].sha != NULL; ++i) { int count = (int)git_cache_size(&g_repo->objects); - cl_git_pass(git_oid_fromstr(&oid, g_data[i].sha)); + cl_git_pass(git_oid__fromstr(&oid, g_data[i].sha, GIT_OID_SHA1)); cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJECT_ANY)); cl_assert(g_data[i].type == git_object_type(obj)); git_object_free(obj); @@ -136,14 +136,14 @@ static void *cache_parsed(void *arg) git_object *obj; for (i = ((int *)arg)[1]; g_data[i].sha != NULL; i += 2) { - cl_git_pass(git_oid_fromstr(&oid, g_data[i].sha)); + cl_git_pass(git_oid__fromstr(&oid, g_data[i].sha, GIT_OID_SHA1)); cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJECT_ANY)); cl_assert(g_data[i].type == git_object_type(obj)); git_object_free(obj); } for (i = 0; i < ((int *)arg)[1]; i += 2) { - cl_git_pass(git_oid_fromstr(&oid, g_data[i].sha)); + cl_git_pass(git_oid__fromstr(&oid, g_data[i].sha, GIT_OID_SHA1)); cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJECT_ANY)); cl_assert(g_data[i].type == git_object_type(obj)); git_object_free(obj); @@ -162,14 +162,14 @@ static void *cache_raw(void *arg) cl_git_pass(git_repository_odb(&odb, g_repo)); for (i = ((int *)arg)[1]; g_data[i].sha != NULL; i += 2) { - cl_git_pass(git_oid_fromstr(&oid, g_data[i].sha)); + cl_git_pass(git_oid__fromstr(&oid, g_data[i].sha, GIT_OID_SHA1)); cl_git_pass(git_odb_read(&odb_obj, odb, &oid)); cl_assert(g_data[i].type == git_odb_object_type(odb_obj)); git_odb_object_free(odb_obj); } for (i = 0; i < ((int *)arg)[1]; i += 2) { - cl_git_pass(git_oid_fromstr(&oid, g_data[i].sha)); + cl_git_pass(git_oid__fromstr(&oid, g_data[i].sha, GIT_OID_SHA1)); cl_git_pass(git_odb_read(&odb_obj, odb, &oid)); cl_assert(g_data[i].type == git_odb_object_type(odb_obj)); git_odb_object_free(odb_obj); @@ -234,7 +234,7 @@ static void *cache_quick(void *arg) git_oid oid; git_object *obj; - cl_git_pass(git_oid_fromstr(&oid, g_data[4].sha)); + cl_git_pass(git_oid__fromstr(&oid, g_data[4].sha, GIT_OID_SHA1)); cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJECT_ANY)); cl_assert(g_data[4].type == git_object_type(obj)); git_object_free(obj); diff --git a/tests/libgit2/object/commit/commitstagedfile.c b/tests/libgit2/object/commit/commitstagedfile.c index 7322a4e86..61f50b2af 100644 --- a/tests/libgit2/object/commit/commitstagedfile.c +++ b/tests/libgit2/object/commit/commitstagedfile.c @@ -64,9 +64,9 @@ void test_object_commit_commitstagedfile__generate_predictable_object_ids(void) * 100644 blob 9daeafb9864cf43055ae93beb0afd6c7d144bfa4 test.txt */ - cl_git_pass(git_oid_fromstr(&expected_commit_oid, "1fe3126578fc4eca68c193e4a3a0a14a0704624d")); - cl_git_pass(git_oid_fromstr(&expected_tree_oid, "2b297e643c551e76cfa1f93810c50811382f9117")); - cl_git_pass(git_oid_fromstr(&expected_blob_oid, "9daeafb9864cf43055ae93beb0afd6c7d144bfa4")); + cl_git_pass(git_oid__fromstr(&expected_commit_oid, "1fe3126578fc4eca68c193e4a3a0a14a0704624d", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&expected_tree_oid, "2b297e643c551e76cfa1f93810c50811382f9117", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&expected_blob_oid, "9daeafb9864cf43055ae93beb0afd6c7d144bfa4", GIT_OID_SHA1)); /* * Add a new file to the index diff --git a/tests/libgit2/object/commit/parse.c b/tests/libgit2/object/commit/parse.c index 4ff1ad62a..6f9a65507 100644 --- a/tests/libgit2/object/commit/parse.c +++ b/tests/libgit2/object/commit/parse.c @@ -3,7 +3,10 @@ #include "object.h" #include "signature.h" -static void assert_commit_parses(const char *data, size_t datalen, +static void assert_commit_parses( + const char *data, + size_t datalen, + git_oid_t oid_type, const char *expected_treeid, const char *expected_author, const char *expected_committer, @@ -14,7 +17,7 @@ static void assert_commit_parses(const char *data, size_t datalen, git_commit *commit; if (!datalen) datalen = strlen(data); - cl_git_pass(git_object__from_raw((git_object **) &commit, data, datalen, GIT_OBJECT_COMMIT)); + cl_git_pass(git_object__from_raw((git_object **) &commit, data, datalen, GIT_OBJECT_COMMIT, oid_type)); if (expected_author) { git_signature *author; @@ -51,7 +54,7 @@ static void assert_commit_parses(const char *data, size_t datalen, if (expected_treeid) { git_oid tree_oid; - cl_git_pass(git_oid_fromstr(&tree_oid, expected_treeid)); + cl_git_pass(git_oid__fromstr(&tree_oid, expected_treeid, oid_type)); cl_assert_equal_oid(&tree_oid, &commit->tree_id); } @@ -60,15 +63,18 @@ static void assert_commit_parses(const char *data, size_t datalen, git_object__free(&commit->object); } -static void assert_commit_fails(const char *data, size_t datalen) +static void assert_commit_fails( + const char *data, + size_t datalen, + git_oid_t oid_type) { git_object *object; if (!datalen) datalen = strlen(data); - cl_git_fail(git_object__from_raw(&object, data, datalen, GIT_OBJECT_COMMIT)); + cl_git_fail(git_object__from_raw(&object, data, datalen, GIT_OBJECT_COMMIT, oid_type)); } -void test_object_commit_parse__parsing_commit_succeeds(void) +void test_object_commit_parse__sha1_parsing_commit_succeeds(void) { const char *commit = "tree 3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8\n" @@ -77,7 +83,7 @@ void test_object_commit_parse__parsing_commit_succeeds(void) "encoding Encoding\n" "\n" "Message"; - assert_commit_parses(commit, 0, + assert_commit_parses(commit, 0, GIT_OID_SHA1, "3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8", "Author ", "Committer ", @@ -85,7 +91,7 @@ void test_object_commit_parse__parsing_commit_succeeds(void) "Message", 0); } -void test_object_commit_parse__parsing_commit_without_encoding_succeeds(void) +void test_object_commit_parse__sha1_parsing_commit_without_encoding_succeeds(void) { const char *commit = "tree 3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8\n" @@ -93,7 +99,7 @@ void test_object_commit_parse__parsing_commit_without_encoding_succeeds(void) "committer Committer \n" "\n" "Message"; - assert_commit_parses(commit, 0, + assert_commit_parses(commit, 0, GIT_OID_SHA1, "3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8", "Author ", "Committer ", @@ -101,7 +107,7 @@ void test_object_commit_parse__parsing_commit_without_encoding_succeeds(void) "Message", 0); } -void test_object_commit_parse__parsing_commit_with_multiple_authors_succeeds(void) +void test_object_commit_parse__sha1_parsing_commit_with_multiple_authors_succeeds(void) { const char *commit = "tree 3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8\n" @@ -112,7 +118,7 @@ void test_object_commit_parse__parsing_commit_with_multiple_authors_succeeds(voi "committer Committer \n" "\n" "Message"; - assert_commit_parses(commit, 0, + assert_commit_parses(commit, 0, GIT_OID_SHA1, "3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8", "Author1 ", "Committer ", @@ -120,7 +126,7 @@ void test_object_commit_parse__parsing_commit_with_multiple_authors_succeeds(voi "Message", 0); } -void test_object_commit_parse__parsing_commit_with_multiple_committers_succeeds(void) +void test_object_commit_parse__sha1_parsing_commit_with_multiple_committers_succeeds(void) { const char *commit = "tree 3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8\n" @@ -131,7 +137,7 @@ void test_object_commit_parse__parsing_commit_with_multiple_committers_succeeds( "committer Committer4 \n" "\n" "Message"; - assert_commit_parses(commit, 0, + assert_commit_parses(commit, 0, GIT_OID_SHA1, "3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8", "Author ", "Committer1 ", @@ -139,13 +145,13 @@ void test_object_commit_parse__parsing_commit_with_multiple_committers_succeeds( "Message", 0); } -void test_object_commit_parse__parsing_commit_without_message_succeeds(void) +void test_object_commit_parse__sha1_parsing_commit_without_message_succeeds(void) { const char *commit = "tree 3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8\n" "author Author \n" "committer Committer \n"; - assert_commit_parses(commit, 0, + assert_commit_parses(commit, 0, GIT_OID_SHA1, "3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8", "Author ", "Committer ", @@ -153,7 +159,7 @@ void test_object_commit_parse__parsing_commit_without_message_succeeds(void) "", 0); } -void test_object_commit_parse__parsing_commit_with_unknown_fields_succeeds(void) +void test_object_commit_parse__sha1_parsing_commit_with_unknown_fields_succeeds(void) { const char *commit = "tree 3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8\n" @@ -163,7 +169,7 @@ void test_object_commit_parse__parsing_commit_with_unknown_fields_succeeds(void) "more garbage\n" "\n" "Message"; - assert_commit_parses(commit, 0, + assert_commit_parses(commit, 0, GIT_OID_SHA1, "3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8", "Author ", "Committer ", @@ -171,7 +177,7 @@ void test_object_commit_parse__parsing_commit_with_unknown_fields_succeeds(void) "Message", 0); } -void test_object_commit_parse__parsing_commit_with_invalid_tree_fails(void) +void test_object_commit_parse__sha1_parsing_commit_with_invalid_tree_fails(void) { const char *commit = "tree 3e7ac388cadacccdf1xxx5f3445895b71d9cb0f8\n" @@ -179,40 +185,51 @@ void test_object_commit_parse__parsing_commit_with_invalid_tree_fails(void) "committer Committer \n" "\n" "Message"; - assert_commit_fails(commit, 0); + assert_commit_fails(commit, 0, GIT_OID_SHA1); } -void test_object_commit_parse__parsing_commit_without_tree_fails(void) +void test_object_commit_parse__sha1_parsing_commit_with_sha256_tree_fails(void) +{ + const char *commit = + "tree f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736\n" + "author Author \n" + "committer Committer \n" + "\n" + "Message"; + assert_commit_fails(commit, 0, GIT_OID_SHA1); +} + +void test_object_commit_parse__sha1_parsing_commit_without_tree_fails(void) { const char *commit = "author Author \n" "committer Committer \n" "\n" "Message"; - assert_commit_fails(commit, 0); + assert_commit_fails(commit, 0, GIT_OID_SHA1); } -void test_object_commit_parse__parsing_commit_without_author_fails(void) +void test_object_commit_parse__sha1_parsing_commit_without_author_fails(void) { const char *commit = "tree 3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8\n" "committer Committer \n" "\n" "Message"; - assert_commit_fails(commit, 0); + assert_commit_fails(commit, 0, GIT_OID_SHA1); } -void test_object_commit_parse__parsing_commit_without_committer_fails(void) +void test_object_commit_parse__sha1_parsing_commit_without_committer_fails(void) { const char *commit = "tree 3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8\n" "author Author \n" "\n" "Message"; - assert_commit_fails(commit, 0); + assert_commit_fails(commit, 0, GIT_OID_SHA1); } -void test_object_commit_parse__parsing_encoding_will_not_cause_oob_read(void) +void test_object_commit_parse__sha1_parsing_encoding_will_not_cause_oob_read(void) { const char *commit = "tree 3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8\n" @@ -223,10 +240,237 @@ void test_object_commit_parse__parsing_encoding_will_not_cause_oob_read(void) * As we ignore unknown fields, the cut-off encoding field will be * parsed just fine. */ - assert_commit_parses(commit, strlen(commit) - strlen("ncoding foo\n"), + assert_commit_parses( + commit, strlen(commit) - strlen("ncoding foo\n"), + GIT_OID_SHA1, "3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8", "<>", "<>", NULL, "", 0); } + + +void test_object_commit_parse__sha256_parsing_commit_succeeds(void) +{ +#ifndef GIT_EXPERIMENTAL_SHA256 + cl_skip(); +#else + const char *commit = + "tree f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736\n" + "author Author \n" + "committer Committer \n" + "encoding Encoding\n" + "\n" + "Message"; + assert_commit_parses(commit, 0, GIT_OID_SHA256, + "f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736", + "Author ", + "Committer ", + "Encoding", + "Message", 0); +#endif +} + +void test_object_commit_parse__sha256_parsing_commit_without_encoding_succeeds(void) +{ +#ifndef GIT_EXPERIMENTAL_SHA256 + cl_skip(); +#else + const char *commit = + "tree f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736\n" + "author Author \n" + "committer Committer \n" + "\n" + "Message"; + assert_commit_parses(commit, 0, GIT_OID_SHA256, + "f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736", + "Author ", + "Committer ", + NULL, + "Message", 0); +#endif +} + +void test_object_commit_parse__sha256_parsing_commit_with_multiple_authors_succeeds(void) +{ +#ifndef GIT_EXPERIMENTAL_SHA256 + cl_skip(); +#else + const char *commit = + "tree f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736\n" + "author Author1 \n" + "author Author2 \n" + "author Author3 \n" + "author Author4 \n" + "committer Committer \n" + "\n" + "Message"; + assert_commit_parses(commit, 0, GIT_OID_SHA256, + "f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736", + "Author1 ", + "Committer ", + NULL, + "Message", 0); +#endif +} + +void test_object_commit_parse__sha256_parsing_commit_with_multiple_committers_succeeds(void) +{ +#ifndef GIT_EXPERIMENTAL_SHA256 + cl_skip(); +#else + const char *commit = + "tree f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736\n" + "author Author \n" + "committer Committer1 \n" + "committer Committer2 \n" + "committer Committer3 \n" + "committer Committer4 \n" + "\n" + "Message"; + assert_commit_parses(commit, 0, GIT_OID_SHA256, + "f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736", + "Author ", + "Committer1 ", + NULL, + "Message", 0); +#endif +} + +void test_object_commit_parse__sha256_parsing_commit_without_message_succeeds(void) +{ +#ifndef GIT_EXPERIMENTAL_SHA256 + cl_skip(); +#else + const char *commit = + "tree f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736\n" + "author Author \n" + "committer Committer \n"; + assert_commit_parses(commit, 0, GIT_OID_SHA256, + "f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736", + "Author ", + "Committer ", + NULL, + "", 0); +#endif +} + +void test_object_commit_parse__sha256_parsing_commit_with_unknown_fields_succeeds(void) +{ +#ifndef GIT_EXPERIMENTAL_SHA256 + cl_skip(); +#else + const char *commit = + "tree f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736\n" + "author Author \n" + "committer Committer \n" + "foo bar\n" + "more garbage\n" + "\n" + "Message"; + assert_commit_parses(commit, 0, GIT_OID_SHA256, + "f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736", + "Author ", + "Committer ", + NULL, + "Message", 0); +#endif +} + +void test_object_commit_parse__sha256_parsing_commit_with_invalid_tree_fails(void) +{ +#ifndef GIT_EXPERIMENTAL_SHA256 + cl_skip(); +#else + const char *commit = + "tree f2a108f86a3b4fd9adxxxd55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736\n" + "author Author \n" + "committer Committer \n" + "\n" + "Message"; + assert_commit_fails(commit, 0, GIT_OID_SHA256); +#endif +} + +void test_object_commit_parse__sha256_parsing_commit_with_sha1_tree_fails(void) +{ +#ifndef GIT_EXPERIMENTAL_SHA256 + cl_skip(); +#else + const char *commit = + "tree 3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8\n" + "author Author \n" + "committer Committer \n" + "\n" + "Message"; + assert_commit_fails(commit, 0, GIT_OID_SHA256); +#endif +} + +void test_object_commit_parse__sha256_parsing_commit_without_tree_fails(void) +{ +#ifndef GIT_EXPERIMENTAL_SHA256 + cl_skip(); +#else + const char *commit = + "author Author \n" + "committer Committer \n" + "\n" + "Message"; + assert_commit_fails(commit, 0, GIT_OID_SHA256); +#endif +} + +void test_object_commit_parse__sha256_parsing_commit_without_author_fails(void) +{ +#ifndef GIT_EXPERIMENTAL_SHA256 + cl_skip(); +#else + const char *commit = + "tree f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736\n" + "committer Committer \n" + "\n" + "Message"; + assert_commit_fails(commit, 0, GIT_OID_SHA256); +#endif +} + +void test_object_commit_parse__sha256_parsing_commit_without_committer_fails(void) +{ +#ifndef GIT_EXPERIMENTAL_SHA256 + cl_skip(); +#else + const char *commit = + "tree f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736\n" + "author Author \n" + "\n" + "Message"; + assert_commit_fails(commit, 0, GIT_OID_SHA256); +#endif +} + +void test_object_commit_parse__sha256_parsing_encoding_will_not_cause_oob_read(void) +{ +#ifndef GIT_EXPERIMENTAL_SHA256 + cl_skip(); +#else + const char *commit = + "tree f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736\n" + "author <>\n" + "committer <>\n" + "encoding foo\n"; + /* + * As we ignore unknown fields, the cut-off encoding field will be + * parsed just fine. + */ + assert_commit_parses( + commit, strlen(commit) - strlen("ncoding foo\n"), + GIT_OID_SHA256, + "f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736", + "<>", + "<>", + NULL, + "", 0); +#endif +} diff --git a/tests/libgit2/object/lookup.c b/tests/libgit2/object/lookup.c index a7b1ceeb4..7ef1dbd1c 100644 --- a/tests/libgit2/object/lookup.c +++ b/tests/libgit2/object/lookup.c @@ -20,7 +20,7 @@ void test_object_lookup__lookup_wrong_type_returns_enotfound(void) git_oid oid; git_object *object; - cl_git_pass(git_oid_fromstr(&oid, commit)); + cl_git_pass(git_oid__fromstr(&oid, commit, GIT_OID_SHA1)); cl_assert_equal_i( GIT_ENOTFOUND, git_object_lookup(&object, g_repo, &oid, GIT_OBJECT_TAG)); } @@ -31,7 +31,7 @@ void test_object_lookup__lookup_nonexisting_returns_enotfound(void) git_oid oid; git_object *object; - cl_git_pass(git_oid_fromstr(&oid, unknown)); + cl_git_pass(git_oid__fromstr(&oid, unknown, GIT_OID_SHA1)); cl_assert_equal_i( GIT_ENOTFOUND, git_object_lookup(&object, g_repo, &oid, GIT_OBJECT_ANY)); } @@ -42,7 +42,7 @@ void test_object_lookup__lookup_wrong_type_by_abbreviated_id_returns_enotfound(v git_oid oid; git_object *object; - cl_git_pass(git_oid_fromstrn(&oid, commit, strlen(commit))); + cl_git_pass(git_oid__fromstrn(&oid, commit, strlen(commit), GIT_OID_SHA1)); cl_assert_equal_i( GIT_ENOTFOUND, git_object_lookup_prefix(&object, g_repo, &oid, strlen(commit), GIT_OBJECT_TAG)); } @@ -53,7 +53,7 @@ void test_object_lookup__lookup_wrong_type_eventually_returns_enotfound(void) git_oid oid; git_object *object; - cl_git_pass(git_oid_fromstr(&oid, commit)); + cl_git_pass(git_oid__fromstr(&oid, commit, GIT_OID_SHA1)); cl_git_pass(git_object_lookup(&object, g_repo, &oid, GIT_OBJECT_COMMIT)); git_object_free(object); @@ -71,7 +71,7 @@ void test_object_lookup__lookup_corrupt_object_returns_error(void) git_object *object; size_t i; - cl_git_pass(git_oid_fromstr(&oid, commit)); + cl_git_pass(git_oid__fromstr(&oid, commit, GIT_OID_SHA1)); cl_git_pass(git_str_joinpath(&path, git_repository_path(g_repo), file)); cl_git_pass(git_futils_readbuffer(&contents, path.ptr)); @@ -101,7 +101,7 @@ void test_object_lookup__lookup_object_with_wrong_hash_returns_error(void) git_object *object; git_oid oid; - cl_git_pass(git_oid_fromstr(&oid, commit)); + cl_git_pass(git_oid__fromstr(&oid, commit, GIT_OID_SHA1)); /* Copy object to another location with wrong hash */ cl_git_pass(git_str_joinpath(&oldpath, git_repository_path(g_repo), oldloose)); diff --git a/tests/libgit2/object/lookup256.c b/tests/libgit2/object/lookup256.c new file mode 100644 index 000000000..3e1dab661 --- /dev/null +++ b/tests/libgit2/object/lookup256.c @@ -0,0 +1,153 @@ +#include "clar_libgit2.h" + +#include "repository.h" + +#ifdef GIT_EXPERIMENTAL_SHA256 +static git_repository *g_repo; +#endif + +void test_object_lookup256__initialize(void) +{ +#ifdef GIT_EXPERIMENTAL_SHA256 + g_repo = cl_git_sandbox_init("testrepo_256.git"); +#endif +} + +void test_object_lookup256__cleanup(void) +{ +#ifdef GIT_EXPERIMENTAL_SHA256 + cl_git_sandbox_cleanup(); +#endif +} + +void test_object_lookup256__lookup_wrong_type_returns_enotfound(void) +{ +#ifndef GIT_EXPERIMENTAL_SHA256 + cl_skip(); +#else + const char *commit = "4d46d9719e425ef2dfb5bfba098d0b62e21b2b92d0731892eef70db0870e3744"; + git_oid oid; + git_object *object; + + cl_git_pass(git_oid__fromstr(&oid, commit, GIT_OID_SHA256)); + cl_assert_equal_i( + GIT_ENOTFOUND, git_object_lookup(&object, g_repo, &oid, GIT_OBJECT_TAG)); +#endif +} + +void test_object_lookup256__lookup_nonexisting_returns_enotfound(void) +{ +#ifndef GIT_EXPERIMENTAL_SHA256 + cl_skip(); +#else + const char *unknown = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"; + git_oid oid; + git_object *object; + + cl_git_pass(git_oid__fromstr(&oid, unknown, GIT_OID_SHA256)); + cl_assert_equal_i( + GIT_ENOTFOUND, git_object_lookup(&object, g_repo, &oid, GIT_OBJECT_ANY)); +#endif +} + +void test_object_lookup256__lookup_wrong_type_by_abbreviated_id_returns_enotfound(void) +{ +#ifndef GIT_EXPERIMENTAL_SHA256 + cl_skip(); +#else + const char *commit = "4d46d97"; + git_oid oid; + git_object *object; + + cl_git_pass(git_oid__fromstrn(&oid, commit, strlen(commit), GIT_OID_SHA256)); + cl_assert_equal_i( + GIT_ENOTFOUND, git_object_lookup_prefix(&object, g_repo, &oid, strlen(commit), GIT_OBJECT_TAG)); +#endif +} + +void test_object_lookup256__lookup_wrong_type_eventually_returns_enotfound(void) +{ +#ifndef GIT_EXPERIMENTAL_SHA256 + cl_skip(); +#else + const char *commit = "4d46d9719e425ef2dfb5bfba098d0b62e21b2b92d0731892eef70db0870e3744"; + git_oid oid; + git_object *object; + + cl_git_pass(git_oid__fromstr(&oid, commit, GIT_OID_SHA256)); + + cl_git_pass(git_object_lookup(&object, g_repo, &oid, GIT_OBJECT_COMMIT)); + git_object_free(object); + + cl_assert_equal_i( + GIT_ENOTFOUND, git_object_lookup(&object, g_repo, &oid, GIT_OBJECT_TAG)); +#endif +} + +void test_object_lookup256__lookup_corrupt_object_returns_error(void) +{ +#ifndef GIT_EXPERIMENTAL_SHA256 + cl_skip(); +#else + const char *commit = "5ca8959deb2b8327458e0344523eb1ddeeef4bce03e35864640b452f84d26848", + *file = "objects/5c/a8959deb2b8327458e0344523eb1ddeeef4bce03e35864640b452f84d26848"; + git_str path = GIT_STR_INIT, contents = GIT_STR_INIT; + git_oid oid; + git_object *object; + size_t i; + + cl_git_pass(git_oid__fromstr(&oid, commit, GIT_OID_SHA256)); + cl_git_pass(git_str_joinpath(&path, git_repository_path(g_repo), file)); + cl_git_pass(git_futils_readbuffer(&contents, path.ptr)); + + /* Corrupt and try to read the object */ + for (i = 0; i < contents.size; i++) { + contents.ptr[i] ^= 0x1; + cl_git_pass(git_futils_writebuffer(&contents, path.ptr, O_RDWR, 0644)); + cl_git_fail(git_object_lookup(&object, g_repo, &oid, GIT_OBJECT_COMMIT)); + contents.ptr[i] ^= 0x1; + } + + /* Restore original content and assert we can read the object */ + cl_git_pass(git_futils_writebuffer(&contents, path.ptr, O_RDWR, 0644)); + cl_git_pass(git_object_lookup(&object, g_repo, &oid, GIT_OBJECT_COMMIT)); + + git_object_free(object); + git_str_dispose(&path); + git_str_dispose(&contents); +#endif +} + +void test_object_lookup256__lookup_object_with_wrong_hash_returns_error(void) +{ +#ifndef GIT_EXPERIMENTAL_SHA256 + cl_skip(); +#else + const char *oldloose = "objects/5c/a8959deb2b8327458e0344523eb1ddeeef4bce03e35864640b452f84d26848", + *newloose = "objects/5c/a8959deb2b8327458e0344523eb1ddeeef4bce03e35864640b452f84d26840", + *commit = "5ca8959deb2b8327458e0344523eb1ddeeef4bce03e35864640b452f84d26840"; + + git_str oldpath = GIT_STR_INIT, newpath = GIT_STR_INIT; + git_object *object; + git_oid oid; + + cl_git_pass(git_oid__fromstr(&oid, commit, GIT_OID_SHA256)); + + /* Copy object to another location with wrong hash */ + cl_git_pass(git_str_joinpath(&oldpath, git_repository_path(g_repo), oldloose)); + cl_git_pass(git_str_joinpath(&newpath, git_repository_path(g_repo), newloose)); + cl_git_pass(git_futils_cp(oldpath.ptr, newpath.ptr, 0644)); + + /* Verify that lookup fails due to a hashsum mismatch */ + cl_git_fail_with(GIT_EMISMATCH, git_object_lookup(&object, g_repo, &oid, GIT_OBJECT_COMMIT)); + + /* Disable verification and try again */ + cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION, 0)); + cl_git_pass(git_object_lookup(&object, g_repo, &oid, GIT_OBJECT_COMMIT)); + cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION, 1)); + + git_object_free(object); + git_str_dispose(&oldpath); + git_str_dispose(&newpath); +#endif +} diff --git a/tests/libgit2/object/peel.c b/tests/libgit2/object/peel.c index 8be6e42d4..da3ef17e2 100644 --- a/tests/libgit2/object/peel.c +++ b/tests/libgit2/object/peel.c @@ -23,12 +23,12 @@ static void assert_peel( git_object *obj; git_object *peeled; - cl_git_pass(git_oid_fromstr(&oid, sha)); + cl_git_pass(git_oid__fromstr(&oid, sha, GIT_OID_SHA1)); cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJECT_ANY)); cl_git_pass(git_object_peel(&peeled, obj, requested_type)); - cl_git_pass(git_oid_fromstr(&expected_oid, expected_sha)); + cl_git_pass(git_oid__fromstr(&expected_oid, expected_sha, GIT_OID_SHA1)); cl_assert_equal_oid(&expected_oid, git_object_id(peeled)); cl_assert_equal_i(expected_type, git_object_type(peeled)); @@ -43,7 +43,7 @@ static void assert_peel_error(int error, const char *sha, git_object_t requested git_object *obj; git_object *peeled; - cl_git_pass(git_oid_fromstr(&oid, sha)); + cl_git_pass(git_oid__fromstr(&oid, sha, GIT_OID_SHA1)); cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJECT_ANY)); cl_assert_equal_i(error, git_object_peel(&peeled, obj, requested_type)); diff --git a/tests/libgit2/object/raw/chars.c b/tests/libgit2/object/raw/chars.c index cde0bdbf6..cb159e9ac 100644 --- a/tests/libgit2/object/raw/chars.c +++ b/tests/libgit2/object/raw/chars.c @@ -19,10 +19,10 @@ void test_object_raw_chars__find_invalid_chars_in_oid(void) in[38] = (char)i; if (git__fromhex(i) >= 0) { exp[19] = (unsigned char)(git__fromhex(i) << 4); - cl_git_pass(git_oid_fromstr(&out, in)); - cl_assert(memcmp(out.id, exp, sizeof(out.id)) == 0); + cl_git_pass(git_oid__fromstr(&out, in, GIT_OID_SHA1)); + cl_assert(memcmp(out.id, exp, GIT_OID_SHA1_SIZE) == 0); } else { - cl_git_fail(git_oid_fromstr(&out, in)); + cl_git_fail(git_oid__fromstr(&out, in, GIT_OID_SHA1)); } } } @@ -36,6 +36,6 @@ void test_object_raw_chars__build_valid_oid_from_raw_bytes(void) 0xb7, 0x75, 0x21, 0x3c, 0x23, 0xa8, 0xbd, 0x74, 0xf5, 0xe0, }; - git_oid_fromraw(&out, exp); - cl_git_pass(memcmp(out.id, exp, sizeof(out.id))); + git_oid__fromraw(&out, exp, GIT_OID_SHA1); + cl_git_pass(memcmp(out.id, exp, GIT_OID_SHA1_SIZE)); } diff --git a/tests/libgit2/object/raw/compare.c b/tests/libgit2/object/raw/compare.c index 56c016b72..9258eef41 100644 --- a/tests/libgit2/object/raw/compare.c +++ b/tests/libgit2/object/raw/compare.c @@ -13,9 +13,9 @@ void test_object_raw_compare__succeed_on_copy_oid(void) 0xa8, 0xbd, 0x74, 0xf5, 0xe0, }; memset(&b, 0, sizeof(b)); - git_oid_fromraw(&a, exp); + git_oid__fromraw(&a, exp, GIT_OID_SHA1); git_oid_cpy(&b, &a); - cl_git_pass(memcmp(a.id, exp, sizeof(a.id))); + cl_git_pass(memcmp(a.id, exp, GIT_OID_SHA1_SIZE)); } void test_object_raw_compare__succeed_on_oid_comparison_lesser(void) @@ -33,8 +33,8 @@ void test_object_raw_compare__succeed_on_oid_comparison_lesser(void) 0xb7, 0x75, 0x21, 0x3c, 0x23, 0xa8, 0xbd, 0x74, 0xf5, 0xf0, }; - git_oid_fromraw(&a, a_in); - git_oid_fromraw(&b, b_in); + git_oid__fromraw(&a, a_in, GIT_OID_SHA1); + git_oid__fromraw(&b, b_in, GIT_OID_SHA1); cl_assert(git_oid_cmp(&a, &b) < 0); } @@ -47,8 +47,8 @@ void test_object_raw_compare__succeed_on_oid_comparison_equal(void) 0xb7, 0x75, 0x21, 0x3c, 0x23, 0xa8, 0xbd, 0x74, 0xf5, 0xe0, }; - git_oid_fromraw(&a, a_in); - git_oid_fromraw(&b, a_in); + git_oid__fromraw(&a, a_in, GIT_OID_SHA1); + git_oid__fromraw(&b, a_in, GIT_OID_SHA1); cl_assert(git_oid_cmp(&a, &b) == 0); } @@ -67,8 +67,8 @@ void test_object_raw_compare__succeed_on_oid_comparison_greater(void) 0xb7, 0x75, 0x21, 0x3c, 0x23, 0xa8, 0xbd, 0x74, 0xf5, 0xd0, }; - git_oid_fromraw(&a, a_in); - git_oid_fromraw(&b, b_in); + git_oid__fromraw(&a, a_in, GIT_OID_SHA1); + git_oid__fromraw(&b, b_in, GIT_OID_SHA1); cl_assert(git_oid_cmp(&a, &b) > 0); } @@ -76,17 +76,17 @@ void test_object_raw_compare__compare_fmt_oids(void) { const char *exp = "16a0123456789abcdef4b775213c23a8bd74f5e0"; git_oid in; - char out[GIT_OID_HEXSZ + 1]; + char out[GIT_OID_SHA1_HEXSIZE + 1]; - cl_git_pass(git_oid_fromstr(&in, exp)); + cl_git_pass(git_oid__fromstr(&in, exp, GIT_OID_SHA1)); /* Format doesn't touch the last byte */ - out[GIT_OID_HEXSZ] = 'Z'; + out[GIT_OID_SHA1_HEXSIZE] = 'Z'; git_oid_fmt(out, &in); - cl_assert(out[GIT_OID_HEXSZ] == 'Z'); + cl_assert(out[GIT_OID_SHA1_HEXSIZE] == 'Z'); /* Format produced the right result */ - out[GIT_OID_HEXSZ] = '\0'; + out[GIT_OID_SHA1_HEXSIZE] = '\0'; cl_assert_equal_s(exp, out); } @@ -96,7 +96,7 @@ void test_object_raw_compare__compare_static_oids(void) git_oid in; char *out; - cl_git_pass(git_oid_fromstr(&in, exp)); + cl_git_pass(git_oid__fromstr(&in, exp, GIT_OID_SHA1)); out = git_oid_tostr_s(&in); cl_assert(out); @@ -108,16 +108,16 @@ void test_object_raw_compare__compare_pathfmt_oids(void) const char *exp1 = "16a0123456789abcdef4b775213c23a8bd74f5e0"; const char *exp2 = "16/a0123456789abcdef4b775213c23a8bd74f5e0"; git_oid in; - char out[GIT_OID_HEXSZ + 2]; + char out[GIT_OID_SHA1_HEXSIZE + 2]; - cl_git_pass(git_oid_fromstr(&in, exp1)); + cl_git_pass(git_oid__fromstr(&in, exp1, GIT_OID_SHA1)); /* Format doesn't touch the last byte */ - out[GIT_OID_HEXSZ + 1] = 'Z'; + out[GIT_OID_SHA1_HEXSIZE + 1] = 'Z'; git_oid_pathfmt(out, &in); - cl_assert(out[GIT_OID_HEXSZ + 1] == 'Z'); + cl_assert(out[GIT_OID_SHA1_HEXSIZE + 1] == 'Z'); /* Format produced the right result */ - out[GIT_OID_HEXSZ + 1] = '\0'; + out[GIT_OID_SHA1_HEXSIZE + 1] = '\0'; cl_assert_equal_s(exp2, out); } diff --git a/tests/libgit2/object/raw/convert.c b/tests/libgit2/object/raw/convert.c index 40a01ae09..962476b97 100644 --- a/tests/libgit2/object/raw/convert.c +++ b/tests/libgit2/object/raw/convert.c @@ -7,11 +7,11 @@ void test_object_raw_convert__succeed_on_oid_to_string_conversion(void) { const char *exp = "16a0123456789abcdef4b775213c23a8bd74f5e0"; git_oid in; - char out[GIT_OID_HEXSZ + 1]; + char out[GIT_OID_SHA1_HEXSIZE + 1]; char *str; int i; - cl_git_pass(git_oid_fromstr(&in, exp)); + cl_git_pass(git_oid__fromstr(&in, exp, GIT_OID_SHA1)); /* NULL buffer pointer, returns static empty string */ str = git_oid_tostr(NULL, sizeof(out), &in); @@ -29,7 +29,7 @@ void test_object_raw_convert__succeed_on_oid_to_string_conversion(void) str = git_oid_tostr(out, 1, &in); cl_assert(str && *str == '\0' && str == out); - for (i = 1; i < GIT_OID_HEXSZ; i++) { + for (i = 1; i < GIT_OID_SHA1_HEXSIZE; i++) { out[i+1] = 'Z'; str = git_oid_tostr(out, i+1, &in); /* returns out containing c-string */ @@ -44,7 +44,7 @@ void test_object_raw_convert__succeed_on_oid_to_string_conversion(void) /* returns out as hex formatted c-string */ str = git_oid_tostr(out, sizeof(out), &in); - cl_assert(str && str == out && *(str+GIT_OID_HEXSZ) == '\0'); + cl_assert(str && str == out && *(str+GIT_OID_SHA1_HEXSIZE) == '\0'); cl_assert_equal_s(exp, out); } @@ -52,26 +52,26 @@ void test_object_raw_convert__succeed_on_oid_to_string_conversion_big(void) { const char *exp = "16a0123456789abcdef4b775213c23a8bd74f5e0"; git_oid in; - char big[GIT_OID_HEXSZ + 1 + 3]; /* note + 4 => big buffer */ + char big[GIT_OID_SHA1_HEXSIZE + 1 + 3]; /* note + 4 => big buffer */ char *str; - cl_git_pass(git_oid_fromstr(&in, exp)); + cl_git_pass(git_oid__fromstr(&in, exp, GIT_OID_SHA1)); /* place some tail material */ - big[GIT_OID_HEXSZ+0] = 'W'; /* should be '\0' afterwards */ - big[GIT_OID_HEXSZ+1] = 'X'; /* should remain untouched */ - big[GIT_OID_HEXSZ+2] = 'Y'; /* ditto */ - big[GIT_OID_HEXSZ+3] = 'Z'; /* ditto */ + big[GIT_OID_SHA1_HEXSIZE+0] = 'W'; /* should be '\0' afterwards */ + big[GIT_OID_SHA1_HEXSIZE+1] = 'X'; /* should remain untouched */ + big[GIT_OID_SHA1_HEXSIZE+2] = 'Y'; /* ditto */ + big[GIT_OID_SHA1_HEXSIZE+3] = 'Z'; /* ditto */ /* returns big as hex formatted c-string */ str = git_oid_tostr(big, sizeof(big), &in); - cl_assert(str && str == big && *(str+GIT_OID_HEXSZ) == '\0'); + cl_assert(str && str == big && *(str+GIT_OID_SHA1_HEXSIZE) == '\0'); cl_assert_equal_s(exp, big); /* check tail material is untouched */ - cl_assert(str && str == big && *(str+GIT_OID_HEXSZ+1) == 'X'); - cl_assert(str && str == big && *(str+GIT_OID_HEXSZ+2) == 'Y'); - cl_assert(str && str == big && *(str+GIT_OID_HEXSZ+3) == 'Z'); + cl_assert(str && str == big && *(str+GIT_OID_SHA1_HEXSIZE+1) == 'X'); + cl_assert(str && str == big && *(str+GIT_OID_SHA1_HEXSIZE+2) == 'Y'); + cl_assert(str && str == big && *(str+GIT_OID_SHA1_HEXSIZE+3) == 'Z'); } static void check_partial_oid( @@ -86,14 +86,14 @@ void test_object_raw_convert__convert_oid_partially(void) { const char *exp = "16a0123456789abcdef4b775213c23a8bd74f5e0"; git_oid in; - char big[GIT_OID_HEXSZ + 1 + 3]; /* note + 4 => big buffer */ + char big[GIT_OID_SHA1_HEXSIZE + 1 + 3]; /* note + 4 => big buffer */ - cl_git_pass(git_oid_fromstr(&in, exp)); + cl_git_pass(git_oid__fromstr(&in, exp, GIT_OID_SHA1)); git_oid_nfmt(big, sizeof(big), &in); cl_assert_equal_s(exp, big); - git_oid_nfmt(big, GIT_OID_HEXSZ + 1, &in); + git_oid_nfmt(big, GIT_OID_SHA1_HEXSIZE + 1, &in); cl_assert_equal_s(exp, big); check_partial_oid(big, 1, &in, "1"); @@ -102,11 +102,11 @@ void test_object_raw_convert__convert_oid_partially(void) check_partial_oid(big, 4, &in, "16a0"); check_partial_oid(big, 5, &in, "16a01"); - check_partial_oid(big, GIT_OID_HEXSZ, &in, exp); + check_partial_oid(big, GIT_OID_SHA1_HEXSIZE, &in, exp); check_partial_oid( - big, GIT_OID_HEXSZ - 1, &in, "16a0123456789abcdef4b775213c23a8bd74f5e"); + big, GIT_OID_SHA1_HEXSIZE - 1, &in, "16a0123456789abcdef4b775213c23a8bd74f5e"); check_partial_oid( - big, GIT_OID_HEXSZ - 2, &in, "16a0123456789abcdef4b775213c23a8bd74f5"); + big, GIT_OID_SHA1_HEXSIZE - 2, &in, "16a0123456789abcdef4b775213c23a8bd74f5"); check_partial_oid( - big, GIT_OID_HEXSZ - 3, &in, "16a0123456789abcdef4b775213c23a8bd74f"); + big, GIT_OID_SHA1_HEXSIZE - 3, &in, "16a0123456789abcdef4b775213c23a8bd74f"); } diff --git a/tests/libgit2/object/raw/fromstr.c b/tests/libgit2/object/raw/fromstr.c index 8c11c105f..302d362d7 100644 --- a/tests/libgit2/object/raw/fromstr.c +++ b/tests/libgit2/object/raw/fromstr.c @@ -6,9 +6,9 @@ void test_object_raw_fromstr__fail_on_invalid_oid_string(void) { git_oid out; - cl_git_fail(git_oid_fromstr(&out, "")); - cl_git_fail(git_oid_fromstr(&out, "moo")); - cl_git_fail(git_oid_fromstr(&out, "16a67770b7d8d72317c4b775213c23a8bd74f5ez")); + cl_git_fail(git_oid__fromstr(&out, "", GIT_OID_SHA1)); + cl_git_fail(git_oid__fromstr(&out, "moo", GIT_OID_SHA1)); + cl_git_fail(git_oid__fromstr(&out, "16a67770b7d8d72317c4b775213c23a8bd74f5ez", GIT_OID_SHA1)); } void test_object_raw_fromstr__succeed_on_valid_oid_string(void) @@ -21,10 +21,9 @@ void test_object_raw_fromstr__succeed_on_valid_oid_string(void) 0xa8, 0xbd, 0x74, 0xf5, 0xe0, }; - cl_git_pass(git_oid_fromstr(&out, "16a67770b7d8d72317c4b775213c23a8bd74f5e0")); - cl_git_pass(memcmp(out.id, exp, sizeof(out.id))); - - cl_git_pass(git_oid_fromstr(&out, "16A67770B7D8D72317C4b775213C23A8BD74F5E0")); - cl_git_pass(memcmp(out.id, exp, sizeof(out.id))); + cl_git_pass(git_oid__fromstr(&out, "16a67770b7d8d72317c4b775213c23a8bd74f5e0", GIT_OID_SHA1)); + cl_git_pass(memcmp(out.id, exp, GIT_OID_SHA1_SIZE)); + cl_git_pass(git_oid__fromstr(&out, "16A67770B7D8D72317C4b775213C23A8BD74F5E0", GIT_OID_SHA1)); + cl_git_pass(memcmp(out.id, exp, GIT_OID_SHA1_SIZE)); } diff --git a/tests/libgit2/object/raw/hash.c b/tests/libgit2/object/raw/hash.c index 8f22fe0ee..0df1afc3a 100644 --- a/tests/libgit2/object/raw/hash.c +++ b/tests/libgit2/object/raw/hash.c @@ -8,11 +8,11 @@ static void hash_object_pass(git_oid *oid, git_rawobj *obj) { - cl_git_pass(git_odb_hash(oid, obj->data, obj->len, obj->type)); + cl_git_pass(git_odb__hash(oid, obj->data, obj->len, obj->type, GIT_OID_SHA1)); } static void hash_object_fail(git_oid *oid, git_rawobj *obj) { - cl_git_fail(git_odb_hash(oid, obj->data, obj->len, obj->type)); + cl_git_fail(git_odb__hash(oid, obj->data, obj->len, obj->type, GIT_OID_SHA1)); } static char *hello_id = "22596363b3de40b06f981fb85d82312e8c0ed511"; @@ -32,16 +32,16 @@ void test_object_raw_hash__hash_by_blocks(void) /* should already be init'd */ cl_git_pass(git_hash_update(&ctx, hello_text, strlen(hello_text))); cl_git_pass(git_hash_final(hash, &ctx)); - cl_git_pass(git_oid_fromraw(&id2, hash)); - cl_git_pass(git_oid_fromstr(&id1, hello_id)); + cl_git_pass(git_oid__fromraw(&id2, hash, GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&id1, hello_id, GIT_OID_SHA1)); cl_assert(git_oid_cmp(&id1, &id2) == 0); /* reinit should permit reuse */ cl_git_pass(git_hash_init(&ctx)); cl_git_pass(git_hash_update(&ctx, bye_text, strlen(bye_text))); cl_git_pass(git_hash_final(hash, &ctx)); - cl_git_pass(git_oid_fromraw(&id2, hash)); - cl_git_pass(git_oid_fromstr(&id1, bye_id)); + cl_git_pass(git_oid__fromraw(&id2, hash, GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&id1, bye_id, GIT_OID_SHA1)); cl_assert(git_oid_cmp(&id1, &id2) == 0); git_hash_ctx_cleanup(&ctx); @@ -52,9 +52,9 @@ void test_object_raw_hash__hash_buffer_in_single_call(void) git_oid id1, id2; unsigned char hash[GIT_HASH_SHA1_SIZE]; - cl_git_pass(git_oid_fromstr(&id1, hello_id)); + cl_git_pass(git_oid__fromstr(&id1, hello_id, GIT_OID_SHA1)); cl_git_pass(git_hash_buf(hash, hello_text, strlen(hello_text), GIT_HASH_ALGORITHM_SHA1)); - cl_git_pass(git_oid_fromraw(&id2, hash)); + cl_git_pass(git_oid__fromraw(&id2, hash, GIT_OID_SHA1)); cl_assert(git_oid_cmp(&id1, &id2) == 0); } @@ -62,15 +62,17 @@ void test_object_raw_hash__hash_vector(void) { git_oid id1, id2; git_str_vec vec[2]; + unsigned char hash[GIT_HASH_SHA1_SIZE]; - cl_git_pass(git_oid_fromstr(&id1, hello_id)); + cl_git_pass(git_oid__fromstr(&id1, hello_id, GIT_OID_SHA1)); vec[0].data = hello_text; vec[0].len = 4; vec[1].data = hello_text+4; vec[1].len = strlen(hello_text)-4; - git_hash_vec(id2.id, vec, 2, GIT_HASH_ALGORITHM_SHA1); + git_hash_vec(hash, vec, 2, GIT_HASH_ALGORITHM_SHA1); + git_oid__fromraw(&id2, hash, GIT_OID_SHA1); cl_assert(git_oid_cmp(&id1, &id2) == 0); } @@ -79,7 +81,7 @@ void test_object_raw_hash__hash_junk_data(void) { git_oid id, id_zero; - cl_git_pass(git_oid_fromstr(&id_zero, zero_id)); + cl_git_pass(git_oid__fromstr(&id_zero, zero_id, GIT_OID_SHA1)); /* invalid types: */ junk_obj.data = some_data; @@ -114,7 +116,7 @@ void test_object_raw_hash__hash_commit_object(void) { git_oid id1, id2; - cl_git_pass(git_oid_fromstr(&id1, commit_id)); + cl_git_pass(git_oid__fromstr(&id1, commit_id, GIT_OID_SHA1)); hash_object_pass(&id2, &commit_obj); cl_assert(git_oid_cmp(&id1, &id2) == 0); } @@ -123,7 +125,7 @@ void test_object_raw_hash__hash_tree_object(void) { git_oid id1, id2; - cl_git_pass(git_oid_fromstr(&id1, tree_id)); + cl_git_pass(git_oid__fromstr(&id1, tree_id, GIT_OID_SHA1)); hash_object_pass(&id2, &tree_obj); cl_assert(git_oid_cmp(&id1, &id2) == 0); } @@ -132,7 +134,7 @@ void test_object_raw_hash__hash_tag_object(void) { git_oid id1, id2; - cl_git_pass(git_oid_fromstr(&id1, tag_id)); + cl_git_pass(git_oid__fromstr(&id1, tag_id, GIT_OID_SHA1)); hash_object_pass(&id2, &tag_obj); cl_assert(git_oid_cmp(&id1, &id2) == 0); } @@ -141,7 +143,7 @@ void test_object_raw_hash__hash_zero_length_object(void) { git_oid id1, id2; - cl_git_pass(git_oid_fromstr(&id1, zero_id)); + cl_git_pass(git_oid__fromstr(&id1, zero_id, GIT_OID_SHA1)); hash_object_pass(&id2, &zero_obj); cl_assert(git_oid_cmp(&id1, &id2) == 0); } @@ -150,7 +152,7 @@ void test_object_raw_hash__hash_one_byte_object(void) { git_oid id1, id2; - cl_git_pass(git_oid_fromstr(&id1, one_id)); + cl_git_pass(git_oid__fromstr(&id1, one_id, GIT_OID_SHA1)); hash_object_pass(&id2, &one_obj); cl_assert(git_oid_cmp(&id1, &id2) == 0); } @@ -159,7 +161,7 @@ void test_object_raw_hash__hash_two_byte_object(void) { git_oid id1, id2; - cl_git_pass(git_oid_fromstr(&id1, two_id)); + cl_git_pass(git_oid__fromstr(&id1, two_id, GIT_OID_SHA1)); hash_object_pass(&id2, &two_obj); cl_assert(git_oid_cmp(&id1, &id2) == 0); } @@ -168,7 +170,7 @@ void test_object_raw_hash__hash_multi_byte_object(void) { git_oid id1, id2; - cl_git_pass(git_oid_fromstr(&id1, some_id)); + cl_git_pass(git_oid__fromstr(&id1, some_id, GIT_OID_SHA1)); hash_object_pass(&id2, &some_obj); cl_assert(git_oid_cmp(&id1, &id2) == 0); } diff --git a/tests/libgit2/object/raw/short.c b/tests/libgit2/object/raw/short.c index cc2b5f62a..f867e6ba1 100644 --- a/tests/libgit2/object/raw/short.c +++ b/tests/libgit2/object/raw/short.c @@ -17,7 +17,7 @@ void test_object_raw_short__oid_shortener_no_duplicates(void) git_oid_shorten_add(os, "16a0123456789abcdef4b775213c23a8bd74f5e0"); min_len = git_oid_shorten_add(os, "ce08fe4884650f067bd5703b6a59a8b3b3c99a09"); - cl_assert(min_len == GIT_OID_HEXSZ + 1); + cl_assert(min_len == GIT_OID_SHA1_HEXSIZE + 1); git_oid_shorten_free(os); } @@ -36,11 +36,11 @@ static int insert_sequential_oids( p_snprintf(numbuf, sizeof(numbuf), "%u", (unsigned int)i); git_hash_buf(hashbuf, numbuf, strlen(numbuf), GIT_HASH_ALGORITHM_SHA1); - git_oid_fromraw(&oid, hashbuf); + git_oid__fromraw(&oid, hashbuf, GIT_OID_SHA1); - oids[i] = git__malloc(GIT_OID_HEXSZ + 1); + oids[i] = git__malloc(GIT_OID_SHA1_HEXSIZE + 1); cl_assert(oids[i]); - git_oid_nfmt(oids[i], GIT_OID_HEXSZ + 1, &oid); + git_oid_nfmt(oids[i], GIT_OID_SHA1_HEXSIZE + 1, &oid); min_len = git_oid_shorten_add(os, oids[i]); diff --git a/tests/libgit2/object/raw/size.c b/tests/libgit2/object/raw/size.c index 930c6de23..a45e1d272 100644 --- a/tests/libgit2/object/raw/size.c +++ b/tests/libgit2/object/raw/size.c @@ -6,8 +6,8 @@ void test_object_raw_size__validate_oid_size(void) { git_oid out; - cl_assert(20 == GIT_OID_RAWSZ); - cl_assert(40 == GIT_OID_HEXSZ); - cl_assert(sizeof(out) == GIT_OID_RAWSZ); - cl_assert(sizeof(out.id) == GIT_OID_RAWSZ); + + cl_assert(20 == GIT_OID_SHA1_SIZE); + cl_assert(40 == GIT_OID_SHA1_HEXSIZE); + cl_assert(sizeof(out.id) == GIT_OID_MAX_SIZE); } diff --git a/tests/libgit2/object/raw/write.c b/tests/libgit2/object/raw/write.c index 40e05f357..346053df5 100644 --- a/tests/libgit2/object/raw/write.c +++ b/tests/libgit2/object/raw/write.c @@ -66,8 +66,8 @@ void test_body(object_data *d, git_rawobj *o) git_rawobj tmp; make_odb_dir(); - cl_git_pass(git_odb_open(&db, odb_dir)); - cl_git_pass(git_oid_fromstr(&id1, d->id)); + cl_git_pass(git_odb__open(&db, odb_dir, NULL)); + cl_git_pass(git_oid__fromstr(&id1, d->id, GIT_OID_SHA1)); streaming_write(&id2, db, o); cl_assert(git_oid_cmp(&id1, &id2) == 0); diff --git a/tests/libgit2/object/shortid.c b/tests/libgit2/object/shortid.c index 9b673efeb..69fceeeda 100644 --- a/tests/libgit2/object/shortid.c +++ b/tests/libgit2/object/shortid.c @@ -19,28 +19,28 @@ void test_object_shortid__select(void) git_object *obj; git_buf shorty = {0}; - git_oid_fromstr(&full, "ce013625030ba8dba906f756967f9e9ca394464a"); + git_oid__fromstr(&full, "ce013625030ba8dba906f756967f9e9ca394464a", GIT_OID_SHA1); cl_git_pass(git_object_lookup(&obj, _repo, &full, GIT_OBJECT_ANY)); cl_git_pass(git_object_short_id(&shorty, obj)); cl_assert_equal_i(7, shorty.size); cl_assert_equal_s("ce01362", shorty.ptr); git_object_free(obj); - git_oid_fromstr(&full, "038d718da6a1ebbc6a7780a96ed75a70cc2ad6e2"); + git_oid__fromstr(&full, "038d718da6a1ebbc6a7780a96ed75a70cc2ad6e2", GIT_OID_SHA1); cl_git_pass(git_object_lookup(&obj, _repo, &full, GIT_OBJECT_ANY)); cl_git_pass(git_object_short_id(&shorty, obj)); cl_assert_equal_i(7, shorty.size); cl_assert_equal_s("038d718", shorty.ptr); git_object_free(obj); - git_oid_fromstr(&full, "dea509d097ce692e167dfc6a48a7a280cc5e877e"); + git_oid__fromstr(&full, "dea509d097ce692e167dfc6a48a7a280cc5e877e", GIT_OID_SHA1); cl_git_pass(git_object_lookup(&obj, _repo, &full, GIT_OBJECT_ANY)); cl_git_pass(git_object_short_id(&shorty, obj)); cl_assert_equal_i(9, shorty.size); cl_assert_equal_s("dea509d09", shorty.ptr); git_object_free(obj); - git_oid_fromstr(&full, "dea509d0b3cb8ee0650f6ca210bc83f4678851ba"); + git_oid__fromstr(&full, "dea509d0b3cb8ee0650f6ca210bc83f4678851ba", GIT_OID_SHA1); cl_git_pass(git_object_lookup(&obj, _repo, &full, GIT_OBJECT_ANY)); cl_git_pass(git_object_short_id(&shorty, obj)); cl_assert_equal_i(9, shorty.size); diff --git a/tests/libgit2/object/tag/parse.c b/tests/libgit2/object/tag/parse.c index 2c0635ae4..d7a4d85bf 100644 --- a/tests/libgit2/object/tag/parse.c +++ b/tests/libgit2/object/tag/parse.c @@ -14,12 +14,12 @@ static void assert_tag_parses(const char *data, size_t datalen, if (!datalen) datalen = strlen(data); - cl_git_pass(git_object__from_raw((git_object **) &tag, data, datalen, GIT_OBJECT_TAG)); + cl_git_pass(git_object__from_raw((git_object **) &tag, data, datalen, GIT_OBJECT_TAG, GIT_OID_SHA1)); cl_assert_equal_i(tag->type, GIT_OBJECT_TAG); if (expected_oid) { git_oid oid; - cl_git_pass(git_oid_fromstr(&oid, expected_oid)); + cl_git_pass(git_oid__fromstr(&oid, expected_oid, GIT_OID_SHA1)); cl_assert_equal_oid(&oid, &tag->target); } @@ -54,7 +54,7 @@ static void assert_tag_fails(const char *data, size_t datalen) git_object *object; if (!datalen) datalen = strlen(data); - cl_git_fail(git_object__from_raw(&object, data, datalen, GIT_OBJECT_TAG)); + cl_git_fail(git_object__from_raw(&object, data, datalen, GIT_OBJECT_TAG, GIT_OID_SHA1)); } void test_object_tag_parse__valid_tag_parses(void) diff --git a/tests/libgit2/object/tag/peel.c b/tests/libgit2/object/tag/peel.c index 7456a8e17..db81c5aee 100644 --- a/tests/libgit2/object/tag/peel.c +++ b/tests/libgit2/object/tag/peel.c @@ -29,7 +29,7 @@ static void retrieve_tag_from_oid(git_tag **tag_out, git_repository *repo, const { git_oid oid; - cl_git_pass(git_oid_fromstr(&oid, sha)); + cl_git_pass(git_oid__fromstr(&oid, sha, GIT_OID_SHA1)); cl_git_pass(git_tag_lookup(tag_out, repo, &oid)); } diff --git a/tests/libgit2/object/tag/read.c b/tests/libgit2/object/tag/read.c index 90ba58029..6270b567a 100644 --- a/tests/libgit2/object/tag/read.c +++ b/tests/libgit2/object/tag/read.c @@ -32,9 +32,9 @@ void test_object_tag_read__parse(void) git_commit *commit; git_oid id1, id2, id_commit; - git_oid_fromstr(&id1, tag1_id); - git_oid_fromstr(&id2, tag2_id); - git_oid_fromstr(&id_commit, tagged_commit); + git_oid__fromstr(&id1, tag1_id, GIT_OID_SHA1); + git_oid__fromstr(&id2, tag2_id, GIT_OID_SHA1); + git_oid__fromstr(&id_commit, tagged_commit, GIT_OID_SHA1); cl_git_pass(git_tag_lookup(&tag1, g_repo, &id1)); @@ -67,8 +67,8 @@ void test_object_tag_read__parse_without_tagger(void) /* TODO: This is a little messy */ cl_git_pass(git_repository_open(&bad_tag_repo, cl_fixture("bad_tag.git"))); - git_oid_fromstr(&id, bad_tag_id); - git_oid_fromstr(&id_commit, badly_tagged_commit); + git_oid__fromstr(&id, bad_tag_id, GIT_OID_SHA1); + git_oid__fromstr(&id_commit, badly_tagged_commit, GIT_OID_SHA1); cl_git_pass(git_tag_lookup(&bad_tag, bad_tag_repo, &id)); cl_assert(bad_tag != NULL); @@ -99,8 +99,8 @@ void test_object_tag_read__parse_without_message(void) /* TODO: This is a little messy */ cl_git_pass(git_repository_open(&short_tag_repo, cl_fixture("short_tag.git"))); - git_oid_fromstr(&id, short_tag_id); - git_oid_fromstr(&id_commit, short_tagged_commit); + git_oid__fromstr(&id, short_tag_id, GIT_OID_SHA1); + git_oid__fromstr(&id_commit, short_tagged_commit, GIT_OID_SHA1); cl_git_pass(git_tag_lookup(&short_tag, short_tag_repo, &id)); cl_assert(short_tag != NULL); @@ -127,7 +127,7 @@ void test_object_tag_read__without_tagger_nor_message(void) cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git"))); - cl_git_pass(git_oid_fromstr(&id, taggerless)); + cl_git_pass(git_oid__fromstr(&id, taggerless, GIT_OID_SHA1)); cl_git_pass(git_tag_lookup(&tag, repo, &id)); diff --git a/tests/libgit2/object/tag/write.c b/tests/libgit2/object/tag/write.c index 064f328fd..79e01452a 100644 --- a/tests/libgit2/object/tag/write.c +++ b/tests/libgit2/object/tag/write.c @@ -30,7 +30,7 @@ void test_object_tag_write__basic(void) git_reference *ref_tag; git_object *target; - git_oid_fromstr(&target_id, tagged_commit); + git_oid__fromstr(&target_id, tagged_commit, GIT_OID_SHA1); cl_git_pass(git_object_lookup(&target, g_repo, &target_id, GIT_OBJECT_COMMIT)); /* create signature */ @@ -72,7 +72,7 @@ void test_object_tag_write__overwrite(void) git_signature *tagger; git_object *target; - git_oid_fromstr(&target_id, tagged_commit); + git_oid__fromstr(&target_id, tagged_commit, GIT_OID_SHA1); cl_git_pass(git_object_lookup(&target, g_repo, &target_id, GIT_OBJECT_COMMIT)); /* create signature */ @@ -99,7 +99,7 @@ void test_object_tag_write__replace(void) git_reference *ref_tag; git_object *target; - git_oid_fromstr(&target_id, tagged_commit); + git_oid__fromstr(&target_id, tagged_commit, GIT_OID_SHA1); cl_git_pass(git_object_lookup(&target, g_repo, &target_id, GIT_OBJECT_COMMIT)); cl_git_pass(git_reference_lookup(&ref_tag, g_repo, "refs/tags/e90810b")); @@ -135,7 +135,7 @@ void test_object_tag_write__lightweight(void) git_reference *ref_tag; git_object *target; - git_oid_fromstr(&target_id, tagged_commit); + git_oid__fromstr(&target_id, tagged_commit, GIT_OID_SHA1); cl_git_pass(git_object_lookup(&target, g_repo, &target_id, GIT_OBJECT_COMMIT)); cl_git_pass(git_tag_create_lightweight( @@ -163,7 +163,7 @@ void test_object_tag_write__lightweight_over_existing(void) git_oid target_id, object_id, existing_object_id; git_object *target; - git_oid_fromstr(&target_id, tagged_commit); + git_oid__fromstr(&target_id, tagged_commit, GIT_OID_SHA1); cl_git_pass(git_object_lookup(&target, g_repo, &target_id, GIT_OBJECT_COMMIT)); cl_assert_equal_i(GIT_EEXISTS, git_tag_create_lightweight( @@ -173,7 +173,7 @@ void test_object_tag_write__lightweight_over_existing(void) target, 0)); - git_oid_fromstr(&existing_object_id, tag2_id); + git_oid__fromstr(&existing_object_id, tag2_id, GIT_OID_SHA1); cl_assert(git_oid_cmp(&object_id, &existing_object_id) == 0); git_object_free(target); @@ -197,7 +197,7 @@ void test_object_tag_write__creating_with_an_invalid_name_returns_EINVALIDSPEC(v git_signature *tagger; git_object *target; - git_oid_fromstr(&target_id, tagged_commit); + git_oid__fromstr(&target_id, tagged_commit, GIT_OID_SHA1); cl_git_pass(git_object_lookup(&target, g_repo, &target_id, GIT_OBJECT_COMMIT)); cl_git_pass(git_signature_new(&tagger, tagger_name, tagger_email, 123456789, 60)); @@ -229,7 +229,7 @@ static void create_annotation(git_oid *tag_id, const char *name) cl_git_pass(git_signature_new(&tagger, tagger_name, tagger_email, 123456789, 60)); - git_oid_fromstr(&target_id, tagged_commit); + git_oid__fromstr(&target_id, tagged_commit, GIT_OID_SHA1); cl_git_pass(git_object_lookup(&target, g_repo, &target_id, GIT_OBJECT_COMMIT)); cl_git_pass(git_tag_annotation_create(tag_id, g_repo, name, target, tagger, "boom!")); @@ -265,7 +265,7 @@ void test_object_tag_write__error_when_create_tag_with_invalid_name(void) git_signature *tagger; git_object *target; - git_oid_fromstr(&target_id, tagged_commit); + git_oid__fromstr(&target_id, tagged_commit, GIT_OID_SHA1); cl_git_pass(git_object_lookup(&target, g_repo, &target_id, GIT_OBJECT_COMMIT)); cl_git_pass(git_signature_new(&tagger, tagger_name, tagger_email, 123456789, 60)); diff --git a/tests/libgit2/object/tree/attributes.c b/tests/libgit2/object/tree/attributes.c index 8654dfa31..285d19804 100644 --- a/tests/libgit2/object/tree/attributes.c +++ b/tests/libgit2/object/tree/attributes.c @@ -21,7 +21,7 @@ void test_object_tree_attributes__ensure_correctness_of_attributes_on_insertion( git_treebuilder *builder; git_oid oid; - cl_git_pass(git_oid_fromstr(&oid, blob_oid)); + cl_git_pass(git_oid__fromstr(&oid, blob_oid, GIT_OID_SHA1)); cl_git_pass(git_treebuilder_new(&builder, repo, NULL)); @@ -39,7 +39,7 @@ void test_object_tree_attributes__group_writable_tree_entries_created_with_an_an const git_tree_entry *entry; - cl_git_pass(git_oid_fromstr(&tid, tree_oid)); + cl_git_pass(git_oid__fromstr(&tid, tree_oid, GIT_OID_SHA1)); cl_git_pass(git_tree_lookup(&tree, repo, &tid)); entry = git_tree_entry_byname(tree, "old_mode.txt"); @@ -56,7 +56,7 @@ void test_object_tree_attributes__treebuilder_reject_invalid_filemode(void) git_oid bid; const git_tree_entry *entry; - cl_git_pass(git_oid_fromstr(&bid, blob_oid)); + cl_git_pass(git_oid__fromstr(&bid, blob_oid, GIT_OID_SHA1)); cl_git_pass(git_treebuilder_new(&builder, repo, NULL)); cl_git_fail(git_treebuilder_insert( @@ -76,7 +76,7 @@ void test_object_tree_attributes__normalize_attributes_when_creating_a_tree_from git_tree *tree; const git_tree_entry *entry; - cl_git_pass(git_oid_fromstr(&tid, tree_oid)); + cl_git_pass(git_oid__fromstr(&tid, tree_oid, GIT_OID_SHA1)); cl_git_pass(git_tree_lookup(&tree, repo, &tid)); cl_git_pass(git_treebuilder_new(&builder, repo, tree)); @@ -107,7 +107,7 @@ void test_object_tree_attributes__normalize_600(void) git_tree *tree; const git_tree_entry *entry; - git_oid_fromstr(&id, "0810fb7818088ff5ac41ee49199b51473b1bd6c7"); + git_oid__fromstr(&id, "0810fb7818088ff5ac41ee49199b51473b1bd6c7", GIT_OID_SHA1); cl_git_pass(git_tree_lookup(&tree, repo, &id)); entry = git_tree_entry_byname(tree, "ListaTeste.xml"); diff --git a/tests/libgit2/object/tree/duplicateentries.c b/tests/libgit2/object/tree/duplicateentries.c index c11ae0d3d..e9774cac3 100644 --- a/tests/libgit2/object/tree/duplicateentries.c +++ b/tests/libgit2/object/tree/duplicateentries.c @@ -45,7 +45,7 @@ static void tree_checker( cl_assert_equal_i(1, (int)git_tree_entrycount(tree)); entry = git_tree_entry_byindex(tree, 0); - cl_git_pass(git_oid_fromstr(&oid, expected_sha)); + cl_git_pass(git_oid__fromstr(&oid, expected_sha, GIT_OID_SHA1)); cl_assert_equal_i(0, git_oid_cmp(&oid, git_tree_entry_id(entry))); cl_assert_equal_i(expected_filemode, git_tree_entry_filemode(entry)); @@ -70,15 +70,17 @@ static void two_blobs(git_treebuilder *bld) git_oid oid; const git_tree_entry *entry; - cl_git_pass(git_oid_fromstr(&oid, - "a8233120f6ad708f843d861ce2b7228ec4e3dec6")); /* blob oid (README) */ + cl_git_pass(git_oid__fromstr(&oid, + "a8233120f6ad708f843d861ce2b7228ec4e3dec6", + GIT_OID_SHA1)); /* blob oid (README) */ cl_git_pass(git_treebuilder_insert( &entry, bld, "duplicate", &oid, GIT_FILEMODE_BLOB)); - cl_git_pass(git_oid_fromstr(&oid, - "a71586c1dfe8a71c6cbf6c129f404c5642ff31bd")); /* blob oid (new.txt) */ + cl_git_pass(git_oid__fromstr(&oid, + "a71586c1dfe8a71c6cbf6c129f404c5642ff31bd", + GIT_OID_SHA1)); /* blob oid (new.txt) */ cl_git_pass(git_treebuilder_insert( &entry, bld, "duplicate", &oid, @@ -90,15 +92,17 @@ static void one_blob_and_one_tree(git_treebuilder *bld) git_oid oid; const git_tree_entry *entry; - cl_git_pass(git_oid_fromstr(&oid, - "a8233120f6ad708f843d861ce2b7228ec4e3dec6")); /* blob oid (README) */ + cl_git_pass(git_oid__fromstr(&oid, + "a8233120f6ad708f843d861ce2b7228ec4e3dec6", + GIT_OID_SHA1)); /* blob oid (README) */ cl_git_pass(git_treebuilder_insert( &entry, bld, "duplicate", &oid, GIT_FILEMODE_BLOB)); - cl_git_pass(git_oid_fromstr(&oid, - "4e0883eeeeebc1fb1735161cea82f7cb5fab7e63")); /* tree oid (a) */ + cl_git_pass(git_oid__fromstr(&oid, + "4e0883eeeeebc1fb1735161cea82f7cb5fab7e63", + GIT_OID_SHA1)); /* tree oid (a) */ cl_git_pass(git_treebuilder_insert( &entry, bld, "duplicate", &oid, @@ -127,17 +131,17 @@ static void add_fake_conflicts(git_index *index) ancestor_entry.path = "duplicate"; ancestor_entry.mode = GIT_FILEMODE_BLOB; GIT_INDEX_ENTRY_STAGE_SET(&ancestor_entry, 1); - git_oid_fromstr(&ancestor_entry.id, "a8233120f6ad708f843d861ce2b7228ec4e3dec6"); + git_oid__fromstr(&ancestor_entry.id, "a8233120f6ad708f843d861ce2b7228ec4e3dec6", GIT_OID_SHA1); our_entry.path = "duplicate"; our_entry.mode = GIT_FILEMODE_BLOB; GIT_INDEX_ENTRY_STAGE_SET(&our_entry, 2); - git_oid_fromstr(&our_entry.id, "45b983be36b73c0788dc9cbcb76cbb80fc7bb057"); + git_oid__fromstr(&our_entry.id, "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", GIT_OID_SHA1); their_entry.path = "duplicate"; their_entry.mode = GIT_FILEMODE_BLOB; GIT_INDEX_ENTRY_STAGE_SET(&their_entry, 3); - git_oid_fromstr(&their_entry.id, "a71586c1dfe8a71c6cbf6c129f404c5642ff31bd"); + git_oid__fromstr(&their_entry.id, "a71586c1dfe8a71c6cbf6c129f404c5642ff31bd", GIT_OID_SHA1); cl_git_pass(git_index_conflict_add(index, &ancestor_entry, &our_entry, &their_entry)); } diff --git a/tests/libgit2/object/tree/frompath.c b/tests/libgit2/object/tree/frompath.c index 86ca47e94..147e53e93 100644 --- a/tests/libgit2/object/tree/frompath.c +++ b/tests/libgit2/object/tree/frompath.c @@ -11,7 +11,7 @@ void test_object_tree_frompath__initialize(void) cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git"))); cl_assert(repo != NULL); - cl_git_pass(git_oid_fromstr(&id, tree_with_subtrees_oid)); + cl_git_pass(git_oid__fromstr(&id, tree_with_subtrees_oid, GIT_OID_SHA1)); cl_git_pass(git_tree_lookup(&tree, repo, &id)); cl_assert(tree != NULL); } diff --git a/tests/libgit2/object/tree/parse.c b/tests/libgit2/object/tree/parse.c index 4e871dcfa..fc985d672 100644 --- a/tests/libgit2/object/tree/parse.c +++ b/tests/libgit2/object/tree/parse.c @@ -26,7 +26,7 @@ static void assert_tree_parses(const char *data, size_t datalen, if (!datalen) datalen = strlen(data); - cl_git_pass(git_object__from_raw((git_object **) &tree, data, datalen, GIT_OBJECT_TREE)); + cl_git_pass(git_object__from_raw((git_object **) &tree, data, datalen, GIT_OBJECT_TREE, GIT_OID_SHA1)); cl_assert_equal_i(git_tree_entrycount(tree), expected_nentries); @@ -35,7 +35,7 @@ static void assert_tree_parses(const char *data, size_t datalen, const git_tree_entry *entry; git_oid oid; - cl_git_pass(git_oid_fromstr(&oid, expected->oid)); + cl_git_pass(git_oid__fromstr(&oid, expected->oid, GIT_OID_SHA1)); cl_assert(entry = git_tree_entry_byname(tree, expected->filename)); cl_assert_equal_s(expected->filename, entry->filename); @@ -51,7 +51,7 @@ static void assert_tree_fails(const char *data, size_t datalen) git_object *object; if (!datalen) datalen = strlen(data); - cl_git_fail(git_object__from_raw(&object, data, datalen, GIT_OBJECT_TREE)); + cl_git_fail(git_object__from_raw(&object, data, datalen, GIT_OBJECT_TREE, GIT_OID_SHA1)); } void test_object_tree_parse__single_blob_parses(void) diff --git a/tests/libgit2/object/tree/read.c b/tests/libgit2/object/tree/read.c index 95a2e70fb..e18637f03 100644 --- a/tests/libgit2/object/tree/read.c +++ b/tests/libgit2/object/tree/read.c @@ -25,7 +25,7 @@ void test_object_tree_read__loaded(void) git_oid id; git_tree *tree; - git_oid_fromstr(&id, tree_oid); + git_oid__fromstr(&id, tree_oid, GIT_OID_SHA1); cl_git_pass(git_tree_lookup(&tree, g_repo, &id)); @@ -48,7 +48,7 @@ void test_object_tree_read__two(void) const git_tree_entry *entry; git_object *obj; - git_oid_fromstr(&id, tree_oid); + git_oid__fromstr(&id, tree_oid, GIT_OID_SHA1); cl_git_pass(git_tree_lookup(&tree, g_repo, &id)); diff --git a/tests/libgit2/object/tree/update.c b/tests/libgit2/object/tree/update.c index 41b50f3e9..1861ac838 100644 --- a/tests/libgit2/object/tree/update.c +++ b/tests/libgit2/object/tree/update.c @@ -21,10 +21,10 @@ void test_object_tree_update__remove_blob(void) const char *path = "README"; git_tree_update updates[] = { - { GIT_TREE_UPDATE_REMOVE, {{0}}, GIT_FILEMODE_BLOB /* ignored */, path}, + { GIT_TREE_UPDATE_REMOVE, GIT_OID_SHA1_ZERO, GIT_FILEMODE_BLOB /* ignored */, path}, }; - cl_git_pass(git_oid_fromstr(&base_id, "c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b")); + cl_git_pass(git_oid__fromstr(&base_id, "c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b", GIT_OID_SHA1)); cl_git_pass(git_tree_lookup(&base_tree, g_repo, &base_id)); /* Create it with an index */ @@ -50,10 +50,10 @@ void test_object_tree_update__remove_blob_deeper(void) const char *path = "subdir/README"; git_tree_update updates[] = { - { GIT_TREE_UPDATE_REMOVE, {{0}}, GIT_FILEMODE_BLOB /* ignored */, path}, + { GIT_TREE_UPDATE_REMOVE, GIT_OID_SHA1_ZERO, GIT_FILEMODE_BLOB /* ignored */, path}, }; - cl_git_pass(git_oid_fromstr(&base_id, "c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b")); + cl_git_pass(git_oid__fromstr(&base_id, "c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b", GIT_OID_SHA1)); cl_git_pass(git_tree_lookup(&base_tree, g_repo, &base_id)); /* Create it with an index */ @@ -80,11 +80,11 @@ void test_object_tree_update__remove_all_entries(void) const char *path2 = "subdir/subdir2/new.txt"; git_tree_update updates[] = { - { GIT_TREE_UPDATE_REMOVE, {{0}}, GIT_FILEMODE_BLOB /* ignored */, path1}, - { GIT_TREE_UPDATE_REMOVE, {{0}}, GIT_FILEMODE_BLOB /* ignored */, path2}, + { GIT_TREE_UPDATE_REMOVE, GIT_OID_SHA1_ZERO, GIT_FILEMODE_BLOB /* ignored */, path1}, + { GIT_TREE_UPDATE_REMOVE, GIT_OID_SHA1_ZERO, GIT_FILEMODE_BLOB /* ignored */, path2}, }; - cl_git_pass(git_oid_fromstr(&base_id, "c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b")); + cl_git_pass(git_oid__fromstr(&base_id, "c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b", GIT_OID_SHA1)); cl_git_pass(git_tree_lookup(&base_tree, g_repo, &base_id)); /* Create it with an index */ @@ -112,10 +112,10 @@ void test_object_tree_update__replace_blob(void) git_index_entry entry = { {0} }; git_tree_update updates[] = { - { GIT_TREE_UPDATE_UPSERT, {{0}}, GIT_FILEMODE_BLOB, path}, + { GIT_TREE_UPDATE_UPSERT, GIT_OID_SHA1_ZERO, GIT_FILEMODE_BLOB, path}, }; - cl_git_pass(git_oid_fromstr(&base_id, "c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b")); + cl_git_pass(git_oid__fromstr(&base_id, "c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b", GIT_OID_SHA1)); cl_git_pass(git_tree_lookup(&base_tree, g_repo, &base_id)); /* Create it with an index */ @@ -123,7 +123,7 @@ void test_object_tree_update__replace_blob(void) cl_git_pass(git_index_read_tree(idx, base_tree)); entry.path = path; - cl_git_pass(git_oid_fromstr(&entry.id, "fa49b077972391ad58037050f2a75f74e3671e92")); + cl_git_pass(git_oid__fromstr(&entry.id, "fa49b077972391ad58037050f2a75f74e3671e92", GIT_OID_SHA1)); entry.mode = GIT_FILEMODE_BLOB; cl_git_pass(git_index_add(idx, &entry)); @@ -131,7 +131,7 @@ void test_object_tree_update__replace_blob(void) git_index_free(idx); /* Perform the same operation via the tree updater */ - cl_git_pass(git_oid_fromstr(&updates[0].id, "fa49b077972391ad58037050f2a75f74e3671e92")); + cl_git_pass(git_oid__fromstr(&updates[0].id, "fa49b077972391ad58037050f2a75f74e3671e92", GIT_OID_SHA1)); cl_git_pass(git_tree_create_updated(&tree_updater_id, g_repo, base_tree, 1, updates)); cl_assert_equal_oid(&tree_index_id, &tree_updater_id); @@ -153,18 +153,18 @@ void test_object_tree_update__add_blobs(void) }; git_tree_update updates[] = { - { GIT_TREE_UPDATE_UPSERT, {{0}}, GIT_FILEMODE_BLOB, paths[0]}, - { GIT_TREE_UPDATE_UPSERT, {{0}}, GIT_FILEMODE_BLOB, paths[1]}, - { GIT_TREE_UPDATE_UPSERT, {{0}}, GIT_FILEMODE_BLOB, paths[2]}, + { GIT_TREE_UPDATE_UPSERT, GIT_OID_SHA1_ZERO, GIT_FILEMODE_BLOB, paths[0]}, + { GIT_TREE_UPDATE_UPSERT, GIT_OID_SHA1_ZERO, GIT_FILEMODE_BLOB, paths[1]}, + { GIT_TREE_UPDATE_UPSERT, GIT_OID_SHA1_ZERO, GIT_FILEMODE_BLOB, paths[2]}, }; - cl_git_pass(git_oid_fromstr(&base_id, "c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b")); + cl_git_pass(git_oid__fromstr(&base_id, "c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b", GIT_OID_SHA1)); entry.mode = GIT_FILEMODE_BLOB; - cl_git_pass(git_oid_fromstr(&entry.id, "fa49b077972391ad58037050f2a75f74e3671e92")); + cl_git_pass(git_oid__fromstr(&entry.id, "fa49b077972391ad58037050f2a75f74e3671e92", GIT_OID_SHA1)); for (i = 0; i < 3; i++) { - cl_git_pass(git_oid_fromstr(&updates[i].id, "fa49b077972391ad58037050f2a75f74e3671e92")); + cl_git_pass(git_oid__fromstr(&updates[i].id, "fa49b077972391ad58037050f2a75f74e3671e92", GIT_OID_SHA1)); } for (i = 0; i < 2; i++) { @@ -210,18 +210,18 @@ void test_object_tree_update__add_blobs_unsorted(void) }; git_tree_update updates[] = { - { GIT_TREE_UPDATE_UPSERT, {{0}}, GIT_FILEMODE_BLOB, paths[0]}, - { GIT_TREE_UPDATE_UPSERT, {{0}}, GIT_FILEMODE_BLOB, paths[1]}, - { GIT_TREE_UPDATE_UPSERT, {{0}}, GIT_FILEMODE_BLOB, paths[2]}, + { GIT_TREE_UPDATE_UPSERT, GIT_OID_SHA1_ZERO, GIT_FILEMODE_BLOB, paths[0]}, + { GIT_TREE_UPDATE_UPSERT, GIT_OID_SHA1_ZERO, GIT_FILEMODE_BLOB, paths[1]}, + { GIT_TREE_UPDATE_UPSERT, GIT_OID_SHA1_ZERO, GIT_FILEMODE_BLOB, paths[2]}, }; - cl_git_pass(git_oid_fromstr(&base_id, "c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b")); + cl_git_pass(git_oid__fromstr(&base_id, "c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b", GIT_OID_SHA1)); entry.mode = GIT_FILEMODE_BLOB; - cl_git_pass(git_oid_fromstr(&entry.id, "fa49b077972391ad58037050f2a75f74e3671e92")); + cl_git_pass(git_oid__fromstr(&entry.id, "fa49b077972391ad58037050f2a75f74e3671e92", GIT_OID_SHA1)); for (i = 0; i < 3; i++) { - cl_git_pass(git_oid_fromstr(&updates[i].id, "fa49b077972391ad58037050f2a75f74e3671e92")); + cl_git_pass(git_oid__fromstr(&updates[i].id, "fa49b077972391ad58037050f2a75f74e3671e92", GIT_OID_SHA1)); } for (i = 0; i < 2; i++) { @@ -258,12 +258,12 @@ void test_object_tree_update__add_conflict(void) int i; git_oid tree_updater_id; git_tree_update updates[] = { - { GIT_TREE_UPDATE_UPSERT, {{0}}, GIT_FILEMODE_BLOB, "a/dir/blob"}, - { GIT_TREE_UPDATE_UPSERT, {{0}}, GIT_FILEMODE_BLOB, "a/dir"}, + { GIT_TREE_UPDATE_UPSERT, GIT_OID_SHA1_ZERO, GIT_FILEMODE_BLOB, "a/dir/blob"}, + { GIT_TREE_UPDATE_UPSERT, GIT_OID_SHA1_ZERO, GIT_FILEMODE_BLOB, "a/dir"}, }; for (i = 0; i < 2; i++) { - cl_git_pass(git_oid_fromstr(&updates[i].id, "a71586c1dfe8a71c6cbf6c129f404c5642ff31bd")); + cl_git_pass(git_oid__fromstr(&updates[i].id, "a71586c1dfe8a71c6cbf6c129f404c5642ff31bd", GIT_OID_SHA1)); } cl_git_fail(git_tree_create_updated(&tree_updater_id, g_repo, NULL, 2, updates)); @@ -274,12 +274,12 @@ void test_object_tree_update__add_conflict2(void) int i; git_oid tree_updater_id; git_tree_update updates[] = { - { GIT_TREE_UPDATE_UPSERT, {{0}}, GIT_FILEMODE_BLOB, "a/dir/blob"}, - { GIT_TREE_UPDATE_UPSERT, {{0}}, GIT_FILEMODE_TREE, "a/dir/blob"}, + { GIT_TREE_UPDATE_UPSERT, GIT_OID_SHA1_ZERO, GIT_FILEMODE_BLOB, "a/dir/blob"}, + { GIT_TREE_UPDATE_UPSERT, GIT_OID_SHA1_ZERO, GIT_FILEMODE_TREE, "a/dir/blob"}, }; for (i = 0; i < 2; i++) { - cl_git_pass(git_oid_fromstr(&updates[i].id, "a71586c1dfe8a71c6cbf6c129f404c5642ff31bd")); + cl_git_pass(git_oid__fromstr(&updates[i].id, "a71586c1dfe8a71c6cbf6c129f404c5642ff31bd", GIT_OID_SHA1)); } cl_git_fail(git_tree_create_updated(&tree_updater_id, g_repo, NULL, 2, updates)); @@ -290,11 +290,11 @@ void test_object_tree_update__remove_invalid_submodule(void) git_tree *baseline; git_oid updated_tree_id, baseline_id; git_tree_update updates[] = { - {GIT_TREE_UPDATE_REMOVE, {{0}}, GIT_FILEMODE_BLOB, "submodule"}, + {GIT_TREE_UPDATE_REMOVE, GIT_OID_SHA1_ZERO, GIT_FILEMODE_BLOB, "submodule"}, }; /* This tree contains a submodule with an all-zero commit for a submodule named 'submodule' */ - cl_git_pass(git_oid_fromstr(&baseline_id, "396c7f1adb7925f51ba13a75f48252f44c5a14a2")); + cl_git_pass(git_oid__fromstr(&baseline_id, "396c7f1adb7925f51ba13a75f48252f44c5a14a2", GIT_OID_SHA1)); cl_git_pass(git_tree_lookup(&baseline, g_repo, &baseline_id)); cl_git_pass(git_tree_create_updated(&updated_tree_id, g_repo, baseline, 1, updates)); diff --git a/tests/libgit2/object/tree/walk.c b/tests/libgit2/object/tree/walk.c index d1fdaa3a0..573a27849 100644 --- a/tests/libgit2/object/tree/walk.c +++ b/tests/libgit2/object/tree/walk.c @@ -33,7 +33,7 @@ void test_object_tree_walk__0(void) git_tree *tree; int ct; - git_oid_fromstr(&id, tree_oid); + git_oid__fromstr(&id, tree_oid, GIT_OID_SHA1); cl_git_pass(git_tree_lookup(&tree, g_repo, &id)); @@ -77,7 +77,7 @@ void test_object_tree_walk__1(void) git_tree *tree; int ct; - git_oid_fromstr(&id, tree_oid); + git_oid__fromstr(&id, tree_oid, GIT_OID_SHA1); cl_git_pass(git_tree_lookup(&tree, g_repo, &id)); @@ -138,7 +138,7 @@ void test_object_tree_walk__2(void) struct treewalk_skip_data data; /* look up a deep tree */ - git_oid_fromstr(&id, "ae90f12eea699729ed24555e40b9fd669da12a12"); + git_oid__fromstr(&id, "ae90f12eea699729ed24555e40b9fd669da12a12", GIT_OID_SHA1); cl_git_pass(git_tree_lookup(&tree, g_repo, &id)); memset(&data, 0, sizeof(data)); diff --git a/tests/libgit2/object/tree/write.c b/tests/libgit2/object/tree/write.c index a4ceb35b6..71a4c54f6 100644 --- a/tests/libgit2/object/tree/write.c +++ b/tests/libgit2/object/tree/write.c @@ -29,9 +29,9 @@ void test_object_tree_write__from_memory(void) git_tree *tree; git_oid id, bid, rid, id2; - git_oid_fromstr(&id, first_tree); - git_oid_fromstr(&id2, second_tree); - git_oid_fromstr(&bid, blob_oid); + git_oid__fromstr(&id, first_tree, GIT_OID_SHA1); + git_oid__fromstr(&id2, second_tree, GIT_OID_SHA1); + git_oid__fromstr(&bid, blob_oid, GIT_OID_SHA1); /* create a second tree from first tree using `git_treebuilder_insert` * on REPOSITORY_FOLDER. @@ -71,10 +71,10 @@ void test_object_tree_write__subtree(void) git_oid id, bid, subtree_id, id2, id3; git_oid id_hiearar; - git_oid_fromstr(&id, first_tree); - git_oid_fromstr(&id2, second_tree); - git_oid_fromstr(&id3, third_tree); - git_oid_fromstr(&bid, blob_oid); + git_oid__fromstr(&id, first_tree, GIT_OID_SHA1); + git_oid__fromstr(&id2, second_tree, GIT_OID_SHA1); + git_oid__fromstr(&id3, third_tree, GIT_OID_SHA1); + git_oid__fromstr(&bid, blob_oid, GIT_OID_SHA1); /* create subtree */ cl_git_pass(git_treebuilder_new(&builder, g_repo, NULL)); @@ -135,8 +135,8 @@ void test_object_tree_write__sorted_subtrees(void) git_oid bid, tid, tree_oid; - cl_git_pass(git_oid_fromstr(&bid, blob_oid)); - cl_git_pass(git_oid_fromstr(&tid, first_tree)); + cl_git_pass(git_oid__fromstr(&bid, blob_oid, GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&tid, first_tree, GIT_OID_SHA1)); cl_git_pass(git_treebuilder_new(&builder, g_repo, NULL)); @@ -195,7 +195,7 @@ void test_object_tree_write__removing_and_re_adding_in_treebuilder(void) git_oid entry_oid, tree_oid; git_tree *tree; - cl_git_pass(git_oid_fromstr(&entry_oid, blob_oid)); + cl_git_pass(git_oid__fromstr(&entry_oid, blob_oid, GIT_OID_SHA1)); cl_git_pass(git_treebuilder_new(&builder, g_repo, NULL)); @@ -286,7 +286,7 @@ void test_object_tree_write__filtering(void) git_oid entry_oid, tree_oid; git_tree *tree; - git_oid_fromstr(&entry_oid, blob_oid); + git_oid__fromstr(&entry_oid, blob_oid, GIT_OID_SHA1); cl_git_pass(git_treebuilder_new(&builder, g_repo, NULL)); @@ -348,7 +348,7 @@ void test_object_tree_write__cruel_paths(void) int count = 0, i, j; git_tree_entry *te; - git_oid_fromstr(&bid, blob_oid); + git_oid__fromstr(&bid, blob_oid, GIT_OID_SHA1); /* create tree */ cl_git_pass(git_treebuilder_new(&builder, g_repo, NULL)); @@ -411,7 +411,7 @@ void test_object_tree_write__protect_filesystems(void) git_treebuilder *builder; git_oid bid; - cl_git_pass(git_oid_fromstr(&bid, "fa49b077972391ad58037050f2a75f74e3671e92")); + cl_git_pass(git_oid__fromstr(&bid, "fa49b077972391ad58037050f2a75f74e3671e92", GIT_OID_SHA1)); /* Ensure that (by default) we can write objects with funny names on * platforms that are not affected. @@ -460,12 +460,14 @@ static void test_invalid_objects(bool should_allow_invalid) "Expected function call to fail: " #expr), \ NULL, 1) - cl_git_pass(git_oid_fromstr(&valid_blob_id, blob_oid)); - cl_git_pass(git_oid_fromstr(&invalid_blob_id, - "1234567890123456789012345678901234567890")); - cl_git_pass(git_oid_fromstr(&valid_tree_id, first_tree)); - cl_git_pass(git_oid_fromstr(&invalid_tree_id, - "0000000000111111111122222222223333333333")); + cl_git_pass(git_oid__fromstr(&valid_blob_id, blob_oid, GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&invalid_blob_id, + "1234567890123456789012345678901234567890", + GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&valid_tree_id, first_tree, GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&invalid_tree_id, + "0000000000111111111122222222223333333333", + GIT_OID_SHA1)); cl_git_pass(git_treebuilder_new(&builder, g_repo, NULL)); @@ -495,7 +497,7 @@ static void test_inserting_submodule(void) git_treebuilder *bld; git_oid sm_id; - cl_git_pass(git_oid_fromstr(&sm_id, "da39a3ee5e6b4b0d3255bfef95601890afd80709")); + cl_git_pass(git_oid__fromstr(&sm_id, "da39a3ee5e6b4b0d3255bfef95601890afd80709", GIT_OID_SHA1)); cl_git_pass(git_treebuilder_new(&bld, g_repo, NULL)); cl_git_pass(git_treebuilder_insert(NULL, bld, "sm", &sm_id, GIT_FILEMODE_COMMIT)); git_treebuilder_free(bld); @@ -516,7 +518,7 @@ void test_object_tree_write__object_validity(void) void test_object_tree_write__invalid_null_oid(void) { git_treebuilder *bld; - git_oid null_oid = {{0}}; + git_oid null_oid = GIT_OID_SHA1_ZERO; cl_git_pass(git_treebuilder_new(&bld, g_repo, NULL)); cl_git_fail(git_treebuilder_insert(NULL, bld, "null_oid_file", &null_oid, GIT_FILEMODE_BLOB)); diff --git a/tests/libgit2/object/validate.c b/tests/libgit2/object/validate.c index 87193deb6..e11038115 100644 --- a/tests/libgit2/object/validate.c +++ b/tests/libgit2/object/validate.c @@ -1,50 +1,154 @@ #include "clar_libgit2.h" -#define VALID_COMMIT "tree bdd24e358576f1baa275df98cdcaf3ac9a3f4233\n" \ - "parent d6d956f1d66210bfcd0484166befab33b5987a39\n" \ - "author Edward Thomson 1638286404 -0500\n" \ - "committer Edward Thomson 1638324642 -0500\n" \ - "\n" \ - "commit go here.\n" -#define VALID_TREE "100644 HEADER\0\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42" +#define VALID_COMMIT_SHA1 \ + "tree bdd24e358576f1baa275df98cdcaf3ac9a3f4233\n" \ + "parent d6d956f1d66210bfcd0484166befab33b5987a39\n" \ + "author Edward Thomson 1638286404 -0500\n" \ + "committer Edward Thomson 1638324642 -0500\n" \ + "\n" \ + "commit go here.\n" -#define INVALID_COMMIT "tree bdd24e358576f1baa275df98cdcaf3ac9a3f4233\n" \ - "parent d6d956f1d66210bfcd0484166befab33b5987a39\n" \ - "committer Edward Thomson 1638324642 -0500\n" \ - "\n" \ - "commit go here.\n" -#define INVALID_TREE "100644 HEADER \x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42" +#define VALID_TREE_SHA1 \ + "100644 HEADER\0\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42" -void test_object_validate__valid(void) +#define INVALID_COMMIT_SHA1 \ + "tree bdd24e358576f1baa275df98cdcaf3ac9a3f4233\n" \ + "parent d6d956f1d66210bfcd0484166befab33b5987a39\n" \ + "committer Edward Thomson 1638324642 -0500\n" \ + "\n" \ + "commit go here.\n" + +#define INVALID_TREE_SHA1 \ + "100644 HEADER \x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42" + +#define VALID_COMMIT_SHA256 \ + "tree d0fc7f52dc42358506e7f3f3be72f5271994abb104b9397ab3e19bb42361504d\n" \ + "parent 652412419a24ba62a1d897f40aeb80eecbf873797b04a1bbb8d71918653ef65b\n" \ + "author Edward Thomson 1638286404 -0500\n" \ + "committer Edward Thomson 1638324642 -0500\n" \ + "\n" \ + "commit go here.\n" + +#define VALID_TREE_SHA256 \ + "100644 HEADER\0\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42" + +#define INVALID_COMMIT_SHA256 \ + "tree d0fc7f52dc42358506e7f3f3be72f5271994abb104b9397ab3e19bb42361504d\n" \ + "parent 652412419a24ba62a1d897f40aeb80eecbf873797b04a1bbb8d71918653ef65b\n" \ + "committer Edward Thomson 1638324642 -0500\n" \ + "\n" \ + "commit go here.\n" + +#define INVALID_TREE_SHA256 \ + "100644 HEADER \x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42" + +#ifdef GIT_EXPERIMENTAL_SHA256 +# define sha1_rawcontent_is_valid(v, c, l, t) \ + git_object_rawcontent_is_valid(v, c, l, t, GIT_OID_SHA1) +#else +# define sha1_rawcontent_is_valid(v, c, l, t) \ + git_object_rawcontent_is_valid(v, c, l, t) +#endif + +void test_object_validate__valid_sha1(void) { int valid; - cl_git_pass(git_object_rawcontent_is_valid(&valid, "", 0, GIT_OBJECT_BLOB)); + cl_git_pass(sha1_rawcontent_is_valid(&valid, "", 0, GIT_OBJECT_BLOB)); cl_assert_equal_i(1, valid); - cl_git_pass(git_object_rawcontent_is_valid(&valid, "foobar", 0, GIT_OBJECT_BLOB)); + cl_git_pass(sha1_rawcontent_is_valid(&valid, "foobar", 0, GIT_OBJECT_BLOB)); cl_assert_equal_i(1, valid); - cl_git_pass(git_object_rawcontent_is_valid(&valid, VALID_COMMIT, CONST_STRLEN(VALID_COMMIT), GIT_OBJECT_COMMIT)); + cl_git_pass(sha1_rawcontent_is_valid(&valid, VALID_COMMIT_SHA1, CONST_STRLEN(VALID_COMMIT_SHA1), GIT_OBJECT_COMMIT)); cl_assert_equal_i(1, valid); - cl_git_pass(git_object_rawcontent_is_valid(&valid, VALID_TREE, CONST_STRLEN(VALID_TREE), GIT_OBJECT_TREE)); + cl_git_pass(sha1_rawcontent_is_valid(&valid, VALID_TREE_SHA1, CONST_STRLEN(VALID_TREE_SHA1), GIT_OBJECT_TREE)); cl_assert_equal_i(1, valid); } -void test_object_validate__invalid(void) +void test_object_validate__cannot_parse_sha256_as_sha1(void) { int valid; - cl_git_pass(git_object_rawcontent_is_valid(&valid, "", 0, GIT_OBJECT_COMMIT)); + cl_git_pass(sha1_rawcontent_is_valid(&valid, VALID_COMMIT_SHA256, CONST_STRLEN(INVALID_COMMIT_SHA256), GIT_OBJECT_COMMIT)); cl_assert_equal_i(0, valid); - cl_git_pass(git_object_rawcontent_is_valid(&valid, "foobar", 0, GIT_OBJECT_COMMIT)); - cl_assert_equal_i(0, valid); - - cl_git_pass(git_object_rawcontent_is_valid(&valid, INVALID_COMMIT, CONST_STRLEN(INVALID_COMMIT), GIT_OBJECT_COMMIT)); - cl_assert_equal_i(0, valid); - - cl_git_pass(git_object_rawcontent_is_valid(&valid, INVALID_TREE, CONST_STRLEN(INVALID_TREE), GIT_OBJECT_TREE)); + cl_git_pass(sha1_rawcontent_is_valid(&valid, INVALID_TREE_SHA256, CONST_STRLEN(INVALID_TREE_SHA256), GIT_OBJECT_TREE)); cl_assert_equal_i(0, valid); } + +void test_object_validate__invalid_sha1(void) +{ + int valid; + + cl_git_pass(sha1_rawcontent_is_valid(&valid, "", 0, GIT_OBJECT_COMMIT)); + cl_assert_equal_i(0, valid); + + cl_git_pass(sha1_rawcontent_is_valid(&valid, "foobar", 0, GIT_OBJECT_COMMIT)); + cl_assert_equal_i(0, valid); + + cl_git_pass(sha1_rawcontent_is_valid(&valid, INVALID_COMMIT_SHA1, CONST_STRLEN(INVALID_COMMIT_SHA1), GIT_OBJECT_COMMIT)); + cl_assert_equal_i(0, valid); + + cl_git_pass(sha1_rawcontent_is_valid(&valid, INVALID_TREE_SHA1, CONST_STRLEN(INVALID_TREE_SHA1), GIT_OBJECT_TREE)); + cl_assert_equal_i(0, valid); +} + + +void test_object_validate__valid_sha256(void) +{ +#ifndef GIT_EXPERIMENTAL_SHA256 + cl_skip(); +#else + int valid; + + cl_git_pass(git_object_rawcontent_is_valid(&valid, "", 0, GIT_OBJECT_BLOB, GIT_OID_SHA256)); + cl_assert_equal_i(1, valid); + + cl_git_pass(git_object_rawcontent_is_valid(&valid, "foobar", 0, GIT_OBJECT_BLOB, GIT_OID_SHA256)); + cl_assert_equal_i(1, valid); + + cl_git_pass(git_object_rawcontent_is_valid(&valid, VALID_COMMIT_SHA256, CONST_STRLEN(VALID_COMMIT_SHA256), GIT_OBJECT_COMMIT, GIT_OID_SHA256)); + cl_assert_equal_i(1, valid); + + cl_git_pass(git_object_rawcontent_is_valid(&valid, VALID_TREE_SHA256, CONST_STRLEN(VALID_TREE_SHA256), GIT_OBJECT_TREE, GIT_OID_SHA256)); + cl_assert_equal_i(1, valid); +#endif +} + +void test_object_validate__invalid_sha256(void) +{ +#ifndef GIT_EXPERIMENTAL_SHA256 + cl_skip(); +#else + int valid; + + cl_git_pass(git_object_rawcontent_is_valid(&valid, "", 0, GIT_OBJECT_COMMIT, GIT_OID_SHA256)); + cl_assert_equal_i(0, valid); + + cl_git_pass(git_object_rawcontent_is_valid(&valid, "foobar", 0, GIT_OBJECT_COMMIT, GIT_OID_SHA256)); + cl_assert_equal_i(0, valid); + + cl_git_pass(git_object_rawcontent_is_valid(&valid, INVALID_COMMIT_SHA256, CONST_STRLEN(INVALID_COMMIT_SHA256), GIT_OBJECT_COMMIT, GIT_OID_SHA256)); + cl_assert_equal_i(0, valid); + + cl_git_pass(git_object_rawcontent_is_valid(&valid, INVALID_TREE_SHA256, CONST_STRLEN(INVALID_TREE_SHA256), GIT_OBJECT_TREE, GIT_OID_SHA256)); + cl_assert_equal_i(0, valid); +#endif +} + +void test_object_validate__cannot_parse_sha1_as_sha256(void) +{ +#ifndef GIT_EXPERIMENTAL_SHA256 + cl_skip(); +#else + int valid; + + cl_git_pass(git_object_rawcontent_is_valid(&valid, VALID_COMMIT_SHA1, CONST_STRLEN(INVALID_COMMIT_SHA1), GIT_OBJECT_COMMIT, GIT_OID_SHA256)); + cl_assert_equal_i(0, valid); + + cl_git_pass(git_object_rawcontent_is_valid(&valid, INVALID_TREE_SHA1, CONST_STRLEN(INVALID_TREE_SHA1), GIT_OBJECT_TREE, GIT_OID_SHA256)); + cl_assert_equal_i(0, valid); +#endif +} diff --git a/tests/libgit2/odb/alternates.c b/tests/libgit2/odb/alternates.c index 6c00fda2f..4d2da6b1f 100644 --- a/tests/libgit2/odb/alternates.c +++ b/tests/libgit2/odb/alternates.c @@ -52,7 +52,7 @@ void test_odb_alternates__chained(void) /* Now load B and see if we can find an object from testrepo.git */ cl_git_pass(git_repository_open(&repo, paths[1])); - git_oid_fromstr(&oid, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"); + git_oid__fromstr(&oid, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &oid)); git_commit_free(commit); git_repository_free(repo); @@ -74,7 +74,7 @@ void test_odb_alternates__long_chain(void) /* Now load the last one and see if we can find an object from testrepo.git */ cl_git_pass(git_repository_open(&repo, paths[ARRAY_SIZE(paths)-1])); - git_oid_fromstr(&oid, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"); + git_oid__fromstr(&oid, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", GIT_OID_SHA1); cl_git_fail(git_commit_lookup(&commit, repo, &oid)); git_repository_free(repo); } diff --git a/tests/libgit2/odb/backend/backend_helpers.c b/tests/libgit2/odb/backend/backend_helpers.c index 542799242..c1a0070d6 100644 --- a/tests/libgit2/odb/backend/backend_helpers.c +++ b/tests/libgit2/odb/backend/backend_helpers.c @@ -9,7 +9,7 @@ static int search_object(const fake_object **out, fake_backend *fake, const git_ while (obj && obj->oid) { git_oid current_oid; - git_oid_fromstr(¤t_oid, obj->oid); + git_oid__fromstr(¤t_oid, obj->oid, GIT_OID_SHA1); if (git_oid_ncmp(¤t_oid, oid, len) == 0) { if (found) @@ -34,7 +34,7 @@ static int fake_backend__exists(git_odb_backend *backend, const git_oid *oid) fake->exists_calls++; - return search_object(NULL, fake, oid, GIT_OID_HEXSZ) == GIT_OK; + return search_object(NULL, fake, oid, GIT_OID_SHA1_HEXSIZE) == GIT_OK; } static int fake_backend__exists_prefix( @@ -52,7 +52,7 @@ static int fake_backend__exists_prefix( return error; if (out) - git_oid_fromstr(out, obj->oid); + git_oid__fromstr(out, obj->oid, GIT_OID_SHA1); return 0; } @@ -69,7 +69,7 @@ static int fake_backend__read( fake->read_calls++; - if ((error = search_object(&obj, fake, oid, GIT_OID_HEXSZ)) < 0) + if ((error = search_object(&obj, fake, oid, GIT_OID_SHA1_HEXSIZE)) < 0) return error; *len_p = strlen(obj->content); @@ -91,7 +91,7 @@ static int fake_backend__read_header( fake->read_header_calls++; - if ((error = search_object(&obj, fake, oid, GIT_OID_HEXSZ)) < 0) + if ((error = search_object(&obj, fake, oid, GIT_OID_SHA1_HEXSIZE)) < 0) return error; *len_p = strlen(obj->content); @@ -115,7 +115,7 @@ static int fake_backend__read_prefix( if ((error = search_object(&obj, fake, short_oid, len)) < 0) return error; - git_oid_fromstr(out_oid, obj->oid); + git_oid__fromstr(out_oid, obj->oid, GIT_OID_SHA1); *len_p = strlen(obj->content); *buffer_p = git__strdup(obj->content); *type_p = GIT_OBJECT_BLOB; diff --git a/tests/libgit2/odb/backend/loose.c b/tests/libgit2/odb/backend/loose.c new file mode 100644 index 000000000..781b61d9f --- /dev/null +++ b/tests/libgit2/odb/backend/loose.c @@ -0,0 +1,43 @@ +#include "clar_libgit2.h" +#include "repository.h" +#include "odb.h" +#include "backend_helpers.h" +#include "git2/sys/mempack.h" + +static git_repository *_repo; +static git_odb *_odb; + +void test_odb_backend_loose__initialize(void) +{ + git_odb_backend *backend; + + cl_fixture_sandbox("testrepo.git"); + +#ifdef GIT_EXPERIMENTAL_SHA256 + cl_git_pass(git_odb_backend_loose(&backend, "testrepo.git/objects", NULL)); +#else + cl_git_pass(git_odb_backend_loose(&backend, "testrepo.git/objects", 0, 0, 0, 0)); +#endif + + cl_git_pass(git_odb__new(&_odb, NULL)); + cl_git_pass(git_odb_add_backend(_odb, backend, 10)); + cl_git_pass(git_repository_wrap_odb(&_repo, _odb)); +} + +void test_odb_backend_loose__cleanup(void) +{ + git_odb_free(_odb); + git_repository_free(_repo); + + cl_fixture_cleanup("testrepo.git"); +} + +void test_odb_backend_loose__read(void) +{ + git_oid oid; + git_odb_object *obj; + + cl_git_pass(git_oid__fromstr(&oid, "1385f264afb75a56a5bec74243be9b367ba4ca08", GIT_OID_SHA1)); + cl_git_pass(git_odb_read(&obj, _odb, &oid)); + git_odb_object_free(obj); +} diff --git a/tests/libgit2/odb/backend/mempack.c b/tests/libgit2/odb/backend/mempack.c index 2eeed51aa..eb8ab3cb0 100644 --- a/tests/libgit2/odb/backend/mempack.c +++ b/tests/libgit2/odb/backend/mempack.c @@ -1,5 +1,6 @@ #include "clar_libgit2.h" #include "repository.h" +#include "odb.h" #include "backend_helpers.h" #include "git2/sys/mempack.h" @@ -13,7 +14,7 @@ void test_odb_backend_mempack__initialize(void) git_odb_backend *backend; cl_git_pass(git_mempack_new(&backend)); - cl_git_pass(git_odb_new(&_odb)); + cl_git_pass(git_odb__new(&_odb, NULL)); cl_git_pass(git_odb_add_backend(_odb, backend, 10)); cl_git_pass(git_repository_wrap_odb(&_repo, _odb)); } @@ -34,13 +35,13 @@ void test_odb_backend_mempack__write_succeeds(void) void test_odb_backend_mempack__read_of_missing_object_fails(void) { - cl_git_pass(git_oid_fromstr(&_oid, "f6ea0495187600e7b2288c8ac19c5886383a4633")); + cl_git_pass(git_oid__fromstr(&_oid, "f6ea0495187600e7b2288c8ac19c5886383a4633", GIT_OID_SHA1)); cl_git_fail_with(GIT_ENOTFOUND, git_odb_read(&_obj, _odb, &_oid)); } void test_odb_backend_mempack__exists_of_missing_object_fails(void) { - cl_git_pass(git_oid_fromstr(&_oid, "f6ea0495187600e7b2288c8ac19c5886383a4633")); + cl_git_pass(git_oid__fromstr(&_oid, "f6ea0495187600e7b2288c8ac19c5886383a4633", GIT_OID_SHA1)); cl_assert(git_odb_exists(_odb, &_oid) == 0); } diff --git a/tests/libgit2/odb/backend/multiple.c b/tests/libgit2/odb/backend/multiple.c index 5f1eacd52..97588164d 100644 --- a/tests/libgit2/odb/backend/multiple.c +++ b/tests/libgit2/odb/backend/multiple.c @@ -24,7 +24,7 @@ void test_odb_backend_multiple__initialize(void) { git_odb_backend *backend; - git_oid_fromstr(&_existing_oid, EXISTING_HASH); + git_oid__fromstr(&_existing_oid, EXISTING_HASH, GIT_OID_SHA1); _obj = NULL; _repo = cl_git_sandbox_init("testrepo.git"); diff --git a/tests/libgit2/odb/backend/nobackend.c b/tests/libgit2/odb/backend/nobackend.c index 7484d423b..7d9394c6f 100644 --- a/tests/libgit2/odb/backend/nobackend.c +++ b/tests/libgit2/odb/backend/nobackend.c @@ -1,5 +1,6 @@ #include "clar_libgit2.h" #include "repository.h" +#include "odb.h" #include "git2/sys/repository.h" static git_repository *_repo; @@ -12,7 +13,7 @@ void test_odb_backend_nobackend__initialize(void) cl_git_pass(git_repository_new(&_repo)); cl_git_pass(git_config_new(&config)); - cl_git_pass(git_odb_new(&odb)); + cl_git_pass(git_odb__new(&odb, NULL)); cl_git_pass(git_refdb_new(&refdb, _repo)); git_repository_set_config(_repo, config); diff --git a/tests/libgit2/odb/backend/nonrefreshing.c b/tests/libgit2/odb/backend/nonrefreshing.c index 2db10efbc..5084eb7f7 100644 --- a/tests/libgit2/odb/backend/nonrefreshing.c +++ b/tests/libgit2/odb/backend/nonrefreshing.c @@ -33,8 +33,8 @@ static void setup_repository_and_backend(void) void test_odb_backend_nonrefreshing__initialize(void) { - git_oid_fromstr(&_nonexisting_oid, NONEXISTING_HASH); - git_oid_fromstr(&_existing_oid, EXISTING_HASH); + git_oid__fromstr(&_nonexisting_oid, NONEXISTING_HASH, GIT_OID_SHA1); + git_oid__fromstr(&_existing_oid, EXISTING_HASH, GIT_OID_SHA1); setup_repository_and_backend(); } diff --git a/tests/libgit2/odb/backend/refreshing.c b/tests/libgit2/odb/backend/refreshing.c index 9e49298a8..fcba748ee 100644 --- a/tests/libgit2/odb/backend/refreshing.c +++ b/tests/libgit2/odb/backend/refreshing.c @@ -33,8 +33,8 @@ static void setup_repository_and_backend(void) void test_odb_backend_refreshing__initialize(void) { - git_oid_fromstr(&_nonexisting_oid, NONEXISTING_HASH); - git_oid_fromstr(&_existing_oid, EXISTING_HASH); + git_oid__fromstr(&_nonexisting_oid, NONEXISTING_HASH, GIT_OID_SHA1); + git_oid__fromstr(&_existing_oid, EXISTING_HASH, GIT_OID_SHA1); setup_repository_and_backend(); } diff --git a/tests/libgit2/odb/backend/simple.c b/tests/libgit2/odb/backend/simple.c index 6c9293ac0..25dfd90a2 100644 --- a/tests/libgit2/odb/backend/simple.c +++ b/tests/libgit2/odb/backend/simple.c @@ -49,7 +49,7 @@ void test_odb_backend_simple__read_of_object_succeeds(void) setup_backend(objs); - cl_git_pass(git_oid_fromstr(&_oid, objs[0].oid)); + cl_git_pass(git_oid__fromstr(&_oid, objs[0].oid, GIT_OID_SHA1)); cl_git_pass(git_odb_read(&_obj, _odb, &_oid)); assert_object_contains(_obj, objs[0].content); @@ -64,7 +64,7 @@ void test_odb_backend_simple__read_of_nonexisting_object_fails(void) setup_backend(objs); - cl_git_pass(git_oid_fromstr(&_oid, "f6ea0495187600e7b2288c8ac19c5886383a4633")); + cl_git_pass(git_oid__fromstr(&_oid, "f6ea0495187600e7b2288c8ac19c5886383a4633", GIT_OID_SHA1)); cl_git_fail_with(GIT_ENOTFOUND, git_odb_read(&_obj, _odb, &_oid)); } @@ -77,7 +77,7 @@ void test_odb_backend_simple__read_with_hash_mismatch_fails(void) setup_backend(objs); - cl_git_pass(git_oid_fromstr(&_oid, objs[0].oid)); + cl_git_pass(git_oid__fromstr(&_oid, objs[0].oid, GIT_OID_SHA1)); cl_git_fail_with(GIT_EMISMATCH, git_odb_read(&_obj, _odb, &_oid)); } @@ -89,7 +89,7 @@ void test_odb_backend_simple__read_with_hash_mismatch_succeeds_without_verificat }; setup_backend(objs); - cl_git_pass(git_oid_fromstr(&_oid, objs[0].oid)); + cl_git_pass(git_oid__fromstr(&_oid, objs[0].oid, GIT_OID_SHA1)); cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION, 0)); cl_git_pass(git_odb_read(&_obj, _odb, &_oid)); @@ -106,7 +106,7 @@ void test_odb_backend_simple__read_prefix_succeeds(void) setup_backend(objs); - cl_git_pass(git_oid_fromstr(&_oid, "f6ea0495187600e7b2288c8ac19c5886383a4632")); + cl_git_pass(git_oid__fromstr(&_oid, "f6ea0495187600e7b2288c8ac19c5886383a4632", GIT_OID_SHA1)); cl_git_pass(git_odb_read(&_obj, _odb, &_oid)); assert_object_contains(_obj, objs[0].content); @@ -122,7 +122,7 @@ void test_odb_backend_simple__read_prefix_of_nonexisting_object_fails(void) setup_backend(objs); - cl_git_pass(git_oid_fromstrn(&_oid, hash, strlen(hash))); + cl_git_pass(git_oid__fromstrn(&_oid, hash, strlen(hash), GIT_OID_SHA1)); cl_git_fail_with(GIT_ENOTFOUND, git_odb_read(&_obj, _odb, &_oid)); } @@ -136,7 +136,7 @@ void test_odb_backend_simple__read_with_ambiguous_prefix_fails(void) setup_backend(objs); - cl_git_pass(git_oid_fromstr(&_oid, objs[0].oid)); + cl_git_pass(git_oid__fromstr(&_oid, objs[0].oid, GIT_OID_SHA1)); cl_git_fail_with(GIT_EAMBIGUOUS, git_odb_read_prefix(&_obj, _odb, &_oid, 7)); } @@ -150,7 +150,7 @@ void test_odb_backend_simple__read_with_highly_ambiguous_prefix(void) setup_backend(objs); - cl_git_pass(git_oid_fromstr(&_oid, objs[0].oid)); + cl_git_pass(git_oid__fromstr(&_oid, objs[0].oid, GIT_OID_SHA1)); cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION, 0)); cl_git_fail_with(GIT_EAMBIGUOUS, git_odb_read_prefix(&_obj, _odb, &_oid, 39)); cl_git_pass(git_odb_read_prefix(&_obj, _odb, &_oid, 40)); @@ -166,7 +166,7 @@ void test_odb_backend_simple__exists_succeeds(void) setup_backend(objs); - cl_git_pass(git_oid_fromstr(&_oid, objs[0].oid)); + cl_git_pass(git_oid__fromstr(&_oid, objs[0].oid, GIT_OID_SHA1)); cl_assert(git_odb_exists(_odb, &_oid)); } @@ -179,7 +179,7 @@ void test_odb_backend_simple__exists_fails_for_nonexisting_object(void) setup_backend(objs); - cl_git_pass(git_oid_fromstr(&_oid, "f6ea0495187600e7b2288c8ac19c5886383a4633")); + cl_git_pass(git_oid__fromstr(&_oid, "f6ea0495187600e7b2288c8ac19c5886383a4633", GIT_OID_SHA1)); cl_assert(git_odb_exists(_odb, &_oid) == 0); } @@ -194,7 +194,7 @@ void test_odb_backend_simple__exists_prefix_succeeds(void) setup_backend(objs); - cl_git_pass(git_oid_fromstr(&_oid, objs[0].oid)); + cl_git_pass(git_oid__fromstr(&_oid, objs[0].oid, GIT_OID_SHA1)); cl_git_pass(git_odb_exists_prefix(&found, _odb, &_oid, 12)); cl_assert(git_oid_equal(&found, &_oid)); } @@ -209,7 +209,7 @@ void test_odb_backend_simple__exists_with_ambiguous_prefix_fails(void) setup_backend(objs); - cl_git_pass(git_oid_fromstr(&_oid, objs[0].oid)); + cl_git_pass(git_oid__fromstr(&_oid, objs[0].oid, GIT_OID_SHA1)); cl_git_fail_with(GIT_EAMBIGUOUS, git_odb_exists_prefix(NULL, _odb, &_oid, 7)); } @@ -224,7 +224,7 @@ void test_odb_backend_simple__exists_with_highly_ambiguous_prefix(void) setup_backend(objs); - cl_git_pass(git_oid_fromstr(&_oid, objs[0].oid)); + cl_git_pass(git_oid__fromstr(&_oid, objs[0].oid, GIT_OID_SHA1)); cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION, 0)); cl_git_fail_with(GIT_EAMBIGUOUS, git_odb_exists_prefix(&found, _odb, &_oid, 39)); cl_git_pass(git_odb_exists_prefix(&found, _odb, &_oid, 40)); @@ -237,7 +237,7 @@ void test_odb_backend_simple__null_oid_is_ignored(void) { "0000000000000000000000000000000000000000", "null oid content" }, { NULL, NULL } }; - git_oid null_oid = {{0}}; + git_oid null_oid = GIT_OID_SHA1_ZERO; git_odb_object *obj; setup_backend(objs); diff --git a/tests/libgit2/odb/emptyobjects.c b/tests/libgit2/odb/emptyobjects.c index e3ec62d3f..e7cc668d1 100644 --- a/tests/libgit2/odb/emptyobjects.c +++ b/tests/libgit2/odb/emptyobjects.c @@ -24,7 +24,7 @@ void test_odb_emptyobjects__blob_notfound(void) git_oid id, written_id; git_blob *blob; - cl_git_pass(git_oid_fromstr(&id, "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391")); + cl_git_pass(git_oid__fromstr(&id, "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", GIT_OID_SHA1)); cl_git_fail_with(GIT_ENOTFOUND, git_blob_lookup(&blob, g_repo, &id)); cl_git_pass(git_odb_write(&written_id, g_odb, "", 0, GIT_OBJECT_BLOB)); @@ -36,7 +36,7 @@ void test_odb_emptyobjects__read_tree(void) git_oid id; git_tree *tree; - cl_git_pass(git_oid_fromstr(&id, "4b825dc642cb6eb9a060e54bf8d69288fbee4904")); + cl_git_pass(git_oid__fromstr(&id, "4b825dc642cb6eb9a060e54bf8d69288fbee4904", GIT_OID_SHA1)); cl_git_pass(git_tree_lookup(&tree, g_repo, &id)); cl_assert_equal_i(GIT_OBJECT_TREE, git_object_type((git_object *) tree)); cl_assert_equal_i(0, git_tree_entrycount(tree)); @@ -49,7 +49,7 @@ void test_odb_emptyobjects__read_tree_odb(void) git_oid id; git_odb_object *tree_odb; - cl_git_pass(git_oid_fromstr(&id, "4b825dc642cb6eb9a060e54bf8d69288fbee4904")); + cl_git_pass(git_oid__fromstr(&id, "4b825dc642cb6eb9a060e54bf8d69288fbee4904", GIT_OID_SHA1)); cl_git_pass(git_odb_read(&tree_odb, g_odb, &id)); cl_assert(git_odb_object_data(tree_odb)); cl_assert_equal_s("", git_odb_object_data(tree_odb)); diff --git a/tests/libgit2/odb/foreach.c b/tests/libgit2/odb/foreach.c index c2a448363..56b3e882c 100644 --- a/tests/libgit2/odb/foreach.c +++ b/tests/libgit2/odb/foreach.c @@ -51,8 +51,17 @@ void test_odb_foreach__one_pack(void) git_odb_backend *backend = NULL; int nobj = 0; - cl_git_pass(git_odb_new(&_odb)); - cl_git_pass(git_odb_backend_one_pack(&backend, cl_fixture("testrepo.git/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx"))); + cl_git_pass(git_odb__new(&_odb, NULL)); + +#ifdef GIT_EXPERIMENTAL_SHA256 + cl_git_pass(git_odb_backend_one_pack(&backend, + cl_fixture("testrepo.git/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx"), + NULL)); +#else + cl_git_pass(git_odb_backend_one_pack(&backend, + cl_fixture("testrepo.git/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx"))); +#endif + cl_git_pass(git_odb_add_backend(_odb, backend, 1)); _repo = NULL; diff --git a/tests/libgit2/odb/freshen.c b/tests/libgit2/odb/freshen.c index 2396e3774..e337c82b7 100644 --- a/tests/libgit2/odb/freshen.c +++ b/tests/libgit2/odb/freshen.c @@ -43,7 +43,7 @@ void test_odb_freshen__loose_blob(void) git_oid expected_id, id; struct stat before, after; - cl_git_pass(git_oid_fromstr(&expected_id, LOOSE_BLOB_ID)); + cl_git_pass(git_oid__fromstr(&expected_id, LOOSE_BLOB_ID, GIT_OID_SHA1)); set_time_wayback(&before, LOOSE_BLOB_FN); /* make sure we freshen a blob */ @@ -64,7 +64,7 @@ void test_odb_freshen__readonly_object(void) git_oid expected_id, id; struct stat before, after; - cl_git_pass(git_oid_fromstr(&expected_id, UNIQUE_BLOB_ID)); + cl_git_pass(git_oid__fromstr(&expected_id, UNIQUE_BLOB_ID, GIT_OID_SHA1)); cl_git_pass(git_blob_create_from_buffer(&id, repo, UNIQUE_STR, CONST_STRLEN(UNIQUE_STR))); cl_assert_equal_oid(&expected_id, &id); @@ -89,7 +89,7 @@ void test_odb_freshen__loose_tree(void) git_tree *tree; struct stat before, after; - cl_git_pass(git_oid_fromstr(&expected_id, LOOSE_TREE_ID)); + cl_git_pass(git_oid__fromstr(&expected_id, LOOSE_TREE_ID, GIT_OID_SHA1)); set_time_wayback(&before, LOOSE_TREE_FN); cl_git_pass(git_tree_lookup(&tree, repo, &expected_id)); @@ -113,11 +113,11 @@ void test_odb_freshen__tree_during_commit(void) git_signature *signature; struct stat before, after; - cl_git_pass(git_oid_fromstr(&tree_id, LOOSE_TREE_ID)); + cl_git_pass(git_oid__fromstr(&tree_id, LOOSE_TREE_ID, GIT_OID_SHA1)); cl_git_pass(git_tree_lookup(&tree, repo, &tree_id)); set_time_wayback(&before, LOOSE_TREE_FN); - cl_git_pass(git_oid_fromstr(&parent_id, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750")); + cl_git_pass(git_oid__fromstr(&parent_id, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", GIT_OID_SHA1)); cl_git_pass(git_commit_lookup(&parent, repo, &parent_id)); cl_git_pass(git_signature_new(&signature, @@ -147,7 +147,7 @@ void test_odb_freshen__packed_object(void) struct stat before, after; struct p_timeval old_times[2]; - cl_git_pass(git_oid_fromstr(&expected_id, PACKED_ID)); + cl_git_pass(git_oid__fromstr(&expected_id, PACKED_ID, GIT_OID_SHA1)); old_times[0].tv_sec = 1234567890; old_times[0].tv_usec = 0; diff --git a/tests/libgit2/odb/largefiles.c b/tests/libgit2/odb/largefiles.c index acc786ee4..2ec48102b 100644 --- a/tests/libgit2/odb/largefiles.c +++ b/tests/libgit2/odb/largefiles.c @@ -57,7 +57,7 @@ void test_odb_largefiles__write_from_memory(void) for (i = 0; i < (3041*126103); i++) cl_git_pass(git_str_puts(&buf, "Hello, world.\n")); - git_oid_fromstr(&expected, "3fb56989cca483b21ba7cb0a6edb229d10e1c26c"); + git_oid__fromstr(&expected, "3fb56989cca483b21ba7cb0a6edb229d10e1c26c", GIT_OID_SHA1); cl_git_pass(git_odb_write(&oid, odb, buf.ptr, buf.size, GIT_OBJECT_BLOB)); cl_assert_equal_oid(&expected, &oid); @@ -75,7 +75,7 @@ void test_odb_largefiles__streamwrite(void) !cl_is_env_set("GITTEST_SLOW")) cl_skip(); - git_oid_fromstr(&expected, "3fb56989cca483b21ba7cb0a6edb229d10e1c26c"); + git_oid__fromstr(&expected, "3fb56989cca483b21ba7cb0a6edb229d10e1c26c", GIT_OID_SHA1); writefile(&oid); cl_assert_equal_oid(&expected, &oid); diff --git a/tests/libgit2/odb/loose.c b/tests/libgit2/odb/loose.c index fe013a78c..0409dfb28 100644 --- a/tests/libgit2/odb/loose.c +++ b/tests/libgit2/odb/loose.c @@ -34,24 +34,27 @@ static void cmp_objects(git_rawobj *o, object_data *d) static void test_read_object(object_data *data) { - git_oid id; - git_odb_object *obj; + git_oid id; + git_odb_object *obj; git_odb *odb; git_rawobj tmp; + git_odb_options opts = GIT_ODB_OPTIONS_INIT; - write_object_files(data); + opts.oid_type = data->id_type; - cl_git_pass(git_odb_open(&odb, "test-objects")); - cl_git_pass(git_oid_fromstr(&id, data->id)); - cl_git_pass(git_odb_read(&obj, odb, &id)); + write_object_files(data); + + cl_git_pass(git_odb__open(&odb, "test-objects", &opts)); + cl_git_pass(git_oid__fromstr(&id, data->id, data->id_type)); + cl_git_pass(git_odb_read(&obj, odb, &id)); tmp.data = obj->buffer; tmp.len = obj->cached.size; tmp.type = obj->cached.type; - cmp_objects(&tmp, data); + cmp_objects(&tmp, data); - git_odb_object_free(obj); + git_odb_object_free(obj); git_odb_free(odb); } @@ -61,11 +64,14 @@ static void test_read_header(object_data *data) git_odb *odb; size_t len; git_object_t type; + git_odb_options opts = GIT_ODB_OPTIONS_INIT; + + opts.oid_type = data->id_type; write_object_files(data); - cl_git_pass(git_odb_open(&odb, "test-objects")); - cl_git_pass(git_oid_fromstr(&id, data->id)); + cl_git_pass(git_odb__open(&odb, "test-objects", &opts)); + cl_git_pass(git_oid__fromstr(&id, data->id, data->id_type)); cl_git_pass(git_odb_read_header(&len, &type, odb, &id)); cl_assert_equal_sz(data->dlen, len); @@ -83,11 +89,14 @@ static void test_readstream_object(object_data *data, size_t blocksize) char buf[2048], *ptr = buf; size_t remain; int ret; + git_odb_options opts = GIT_ODB_OPTIONS_INIT; + + opts.oid_type = data->id_type; write_object_files(data); - cl_git_pass(git_odb_open(&odb, "test-objects")); - cl_git_pass(git_oid_fromstr(&id, data->id)); + cl_git_pass(git_odb__open(&odb, "test-objects", &opts)); + cl_git_pass(git_oid__fromstr(&id, data->id, data->id_type)); cl_git_pass(git_odb_open_rstream(&stream, &tmp.len, &tmp.type, odb, &id)); remain = tmp.len; @@ -124,32 +133,64 @@ void test_odb_loose__cleanup(void) cl_fixture_cleanup("test-objects"); } -void test_odb_loose__exists(void) +void test_odb_loose__exists_sha1(void) { git_oid id, id2; git_odb *odb; write_object_files(&one); - cl_git_pass(git_odb_open(&odb, "test-objects")); + cl_git_pass(git_odb__open(&odb, "test-objects", NULL)); - cl_git_pass(git_oid_fromstr(&id, one.id)); + cl_git_pass(git_oid__fromstr(&id, one.id, GIT_OID_SHA1)); cl_assert(git_odb_exists(odb, &id)); - cl_git_pass(git_oid_fromstrp(&id, "8b137891")); + cl_git_pass(git_oid__fromstrp(&id, "8b137891", GIT_OID_SHA1)); cl_git_pass(git_odb_exists_prefix(&id2, odb, &id, 8)); cl_assert_equal_i(0, git_oid_streq(&id2, one.id)); /* Test for a missing object */ - cl_git_pass(git_oid_fromstr(&id, "8b137891791fe96927ad78e64b0aad7bded08baa")); + cl_git_pass(git_oid__fromstr(&id, "8b137891791fe96927ad78e64b0aad7bded08baa", GIT_OID_SHA1)); cl_assert(!git_odb_exists(odb, &id)); - cl_git_pass(git_oid_fromstrp(&id, "8b13789a")); + cl_git_pass(git_oid__fromstrp(&id, "8b13789a", GIT_OID_SHA1)); cl_assert_equal_i(GIT_ENOTFOUND, git_odb_exists_prefix(&id2, odb, &id, 8)); git_odb_free(odb); } -void test_odb_loose__simple_reads(void) +void test_odb_loose__exists_sha256(void) +{ +#ifndef GIT_EXPERIMENTAL_SHA256 + cl_skip(); +#else + git_oid id, id2; + git_odb *odb; + git_odb_options odb_opts = GIT_ODB_OPTIONS_INIT; + + odb_opts.oid_type = GIT_OID_SHA256; + + write_object_files(&one_sha256); + cl_git_pass(git_odb__open(&odb, "test-objects", &odb_opts)); + + cl_git_pass(git_oid__fromstr(&id, one_sha256.id, GIT_OID_SHA256)); + cl_assert(git_odb_exists(odb, &id)); + + cl_git_pass(git_oid__fromstrp(&id, "4c0d52d1", GIT_OID_SHA256)); + cl_git_pass(git_odb_exists_prefix(&id2, odb, &id, 8)); + cl_assert_equal_i(0, git_oid_streq(&id2, one_sha256.id)); + + /* Test for a missing object */ + cl_git_pass(git_oid__fromstr(&id, "4c0d52d180c61d01ce1a91dec5ee58f0cbe65fd59433aea803ab927965493faa", GIT_OID_SHA256)); + cl_assert(!git_odb_exists(odb, &id)); + + cl_git_pass(git_oid__fromstrp(&id, "4c0d52da", GIT_OID_SHA256)); + cl_assert_equal_i(GIT_ENOTFOUND, git_odb_exists_prefix(&id2, odb, &id, 8)); + + git_odb_free(odb); +#endif +} + +void test_odb_loose__simple_reads_sha1(void) { test_read_object(&commit); test_read_object(&tree); @@ -160,7 +201,22 @@ void test_odb_loose__simple_reads(void) test_read_object(&some); } -void test_odb_loose__streaming_reads(void) +void test_odb_loose__simple_reads_sha256(void) +{ +#ifndef GIT_EXPERIMENTAL_SHA256 + cl_skip(); +#else + test_read_object(&commit_sha256); + test_read_object(&tree_sha256); + test_read_object(&tag_sha256); + test_read_object(&zero_sha256); + test_read_object(&one_sha256); + test_read_object(&two_sha256); + test_read_object(&some_sha256); +#endif +} + +void test_odb_loose__streaming_reads_sha1(void) { size_t blocksizes[] = { 1, 2, 4, 16, 99, 1024, 123456789 }; size_t i; @@ -176,7 +232,27 @@ void test_odb_loose__streaming_reads(void) } } -void test_odb_loose__read_header(void) +void test_odb_loose__streaming_reads_sha256(void) +{ +#ifndef GIT_EXPERIMENTAL_SHA256 + cl_skip(); +#else + size_t blocksizes[] = { 1, 2, 4, 16, 99, 1024, 123456789 }; + size_t i; + + for (i = 0; i < ARRAY_SIZE(blocksizes); i++) { + test_readstream_object(&commit_sha256, blocksizes[i]); + test_readstream_object(&tree_sha256, blocksizes[i]); + test_readstream_object(&tag_sha256, blocksizes[i]); + test_readstream_object(&zero_sha256, blocksizes[i]); + test_readstream_object(&one_sha256, blocksizes[i]); + test_readstream_object(&two_sha256, blocksizes[i]); + test_readstream_object(&some_sha256, blocksizes[i]); + } +#endif +} + +void test_odb_loose__read_header_sha1(void) { test_read_header(&commit); test_read_header(&tree); @@ -187,6 +263,21 @@ void test_odb_loose__read_header(void) test_read_header(&some); } +void test_odb_loose__read_header_sha256(void) +{ +#ifndef GIT_EXPERIMENTAL_SHA256 + cl_skip(); +#else + test_read_header(&commit_sha256); + test_read_header(&tree_sha256); + test_read_header(&tag_sha256); + test_read_header(&zero_sha256); + test_read_header(&one_sha256); + test_read_header(&two_sha256); + test_read_header(&some_sha256); +#endif +} + static void test_write_object_permission( mode_t dir_mode, mode_t file_mode, mode_t expected_dir_mode, mode_t expected_file_mode) @@ -196,6 +287,7 @@ static void test_write_object_permission( git_oid oid; struct stat statbuf; mode_t mask, os_mask; + git_odb_backend_loose_options opts = GIT_ODB_BACKEND_LOOSE_OPTIONS_INIT; /* Windows does not return group/user bits from stat, * files are never executable. @@ -209,8 +301,11 @@ static void test_write_object_permission( mask = p_umask(0); p_umask(mask); - cl_git_pass(git_odb_new(&odb)); - cl_git_pass(git_odb_backend_loose(&backend, "test-objects", -1, 0, dir_mode, file_mode)); + opts.dir_mode = dir_mode; + opts.file_mode = file_mode; + + cl_git_pass(git_odb__new(&odb, NULL)); + cl_git_pass(git_odb__backend_loose(&backend, "test-objects", &opts)); cl_git_pass(git_odb_add_backend(odb, backend, 1)); cl_git_pass(git_odb_write(&oid, odb, "Test data\n", 10, GIT_OBJECT_BLOB)); @@ -243,9 +338,16 @@ static void write_object_to_loose_odb(int fsync) git_odb *odb; git_odb_backend *backend; git_oid oid; + git_odb_backend_loose_options opts = GIT_ODB_BACKEND_LOOSE_OPTIONS_INIT; - cl_git_pass(git_odb_new(&odb)); - cl_git_pass(git_odb_backend_loose(&backend, "test-objects", -1, fsync, 0777, 0666)); + if (fsync) + opts.flags |= GIT_ODB_BACKEND_LOOSE_FSYNC; + + opts.dir_mode = 0777; + opts.file_mode = 0666; + + cl_git_pass(git_odb__new(&odb, NULL)); + cl_git_pass(git_odb__backend_loose(&backend, "test-objects", &opts)); cl_git_pass(git_odb_add_backend(odb, backend, 1)); cl_git_pass(git_odb_write(&oid, odb, "Test data\n", 10, GIT_OBJECT_BLOB)); git_odb_free(odb); diff --git a/tests/libgit2/odb/loose_data.h b/tests/libgit2/odb/loose_data.h index c10c9bc7f..1a830740d 100644 --- a/tests/libgit2/odb/loose_data.h +++ b/tests/libgit2/odb/loose_data.h @@ -1,7 +1,8 @@ typedef struct object_data { unsigned char *bytes; /* (compressed) bytes stored in object store */ size_t blen; /* length of data in object store */ - char *id; /* object id (sha1) */ + char *id; /* object id (hex chars) */ + git_oid_t id_type; /* type of object id (sha1 or sha256) */ char *type; /* object type */ char *dir; /* object store (fan-out) directory name */ char *file; /* object store filename */ @@ -9,7 +10,10 @@ typedef struct object_data { size_t dlen; /* length of (uncompressed) object data */ } object_data; -/* one == 8b137891791fe96927ad78e64b0aad7bded08bdc */ +/* + * one == 8b137891791fe96927ad78e64b0aad7bded08bdc (sha1) + * 4c0d52d180c61d01ce1a91dec5ee58f0cbe65fd59433aea803ab927965493fd7 (sha256) + */ static unsigned char one_bytes[] = { 0x31, 0x78, 0x9c, 0xe3, 0x02, 0x00, 0x00, 0x0b, 0x00, 0x0b, @@ -23,6 +27,7 @@ static object_data one = { one_bytes, sizeof(one_bytes), "8b137891791fe96927ad78e64b0aad7bded08bdc", + GIT_OID_SHA1, "blob", "test-objects/8b", "test-objects/8b/137891791fe96927ad78e64b0aad7bded08bdc", @@ -30,8 +35,25 @@ static object_data one = { sizeof(one_data), }; +#ifdef GIT_EXPERIMENTAL_SHA256 +static object_data one_sha256 = { + one_bytes, + sizeof(one_bytes), + "4c0d52d180c61d01ce1a91dec5ee58f0cbe65fd59433aea803ab927965493fd7", + GIT_OID_SHA256, + "blob", + "test-objects/4c", + "test-objects/4c/0d52d180c61d01ce1a91dec5ee58f0cbe65fd59433aea803ab927965493fd7", + one_data, + sizeof(one_data), +}; +#endif -/* commit == 3d7f8a6af076c8c3f20071a8935cdbe8228594d1 */ + +/* + * commit == 3d7f8a6af076c8c3f20071a8935cdbe8228594d1 (sha1) + * a2a430fb63b294f868af4ef6ccc9c3e8256e370859ce578a23837ac85337f562 (sha256) + */ static unsigned char commit_bytes[] = { 0x78, 0x01, 0x85, 0x50, 0xc1, 0x6a, 0xc3, 0x30, 0x0c, 0xdd, 0xd9, 0x5f, 0xa1, 0xfb, 0x96, 0x12, @@ -64,6 +86,42 @@ static unsigned char commit_bytes[] = { 0x1f, 0x78, 0x35, }; +#ifdef GIT_EXPERIMENTAL_SHA256 +static unsigned char commit_bytes_sha256[] = { + 0x78, 0x01, 0x85, 0x90, 0xc1, 0x4e, 0xc3, 0x30, + 0x0c, 0x86, 0x39, 0xe7, 0x29, 0x7c, 0x87, 0x4e, + 0x5d, 0x93, 0xa6, 0x2d, 0x9a, 0x10, 0x13, 0x67, + 0xc4, 0x81, 0xf1, 0x00, 0x4e, 0xe3, 0xb4, 0x91, + 0x9a, 0xa4, 0x4a, 0x53, 0x69, 0x7d, 0x7b, 0x82, + 0x3a, 0x4d, 0x9c, 0xc0, 0xa7, 0xcf, 0xbf, 0xfd, + 0xff, 0xb2, 0xdc, 0x07, 0xe7, 0x6c, 0x02, 0xde, + 0xb4, 0x0f, 0x29, 0x12, 0x01, 0x17, 0x28, 0xda, + 0x5a, 0xa8, 0x5a, 0x54, 0xd2, 0x74, 0x95, 0x90, + 0xa5, 0x12, 0x48, 0xbc, 0x26, 0xa9, 0x9b, 0xae, + 0x11, 0x52, 0x91, 0x94, 0x3d, 0x6f, 0x95, 0x31, + 0x5a, 0x92, 0xe1, 0xaa, 0x17, 0xa6, 0xac, 0x39, + 0xe9, 0xa6, 0x45, 0x2e, 0x15, 0x0a, 0x86, 0x6b, + 0x1a, 0x43, 0x84, 0x33, 0x7c, 0xc1, 0xe5, 0x07, + 0x4e, 0xbb, 0xf0, 0x4a, 0x57, 0x74, 0xf3, 0x44, + 0x87, 0x3e, 0xb8, 0x17, 0x38, 0x56, 0x55, 0xd3, + 0x1e, 0x45, 0xd5, 0x35, 0xf0, 0x58, 0xe6, 0x62, + 0x59, 0xcd, 0x67, 0x24, 0x8a, 0xf0, 0x06, 0x1f, + 0xf0, 0xbe, 0xe3, 0xe9, 0xae, 0xfe, 0xe3, 0x66, + 0x67, 0x08, 0x9e, 0x8a, 0xc9, 0x7a, 0x82, 0xdd, + 0x03, 0xcb, 0xea, 0x1c, 0xc6, 0x8d, 0xb1, 0xcb, + 0x48, 0xa0, 0x82, 0xde, 0x20, 0x18, 0x48, 0x99, + 0x6f, 0x73, 0x47, 0xcb, 0x82, 0x03, 0x3d, 0xe5, + 0xde, 0x27, 0xb4, 0xde, 0xfa, 0x01, 0xcc, 0x1a, + 0xf3, 0x46, 0x04, 0xba, 0xce, 0x13, 0x7a, 0x4c, + 0x36, 0x78, 0x76, 0x73, 0xcd, 0x6b, 0x9c, 0xc3, + 0x42, 0xf7, 0x90, 0x11, 0xfd, 0x40, 0x0b, 0x58, + 0x9f, 0x62, 0xd0, 0x6b, 0x4f, 0x1a, 0xd4, 0xf6, + 0x2b, 0xfe, 0xc0, 0xd8, 0xa7, 0x1d, 0x3c, 0xe9, + 0x22, 0x98, 0x42, 0x6d, 0xcf, 0x7f, 0xbf, 0x83, + 0x7d, 0x03, 0x6d, 0x1e, 0x7e, 0xa9 +}; +#endif + static unsigned char commit_data[] = { 0x74, 0x72, 0x65, 0x65, 0x20, 0x64, 0x66, 0x66, 0x32, 0x64, 0x61, 0x39, 0x30, 0x62, 0x32, 0x35, @@ -112,10 +170,64 @@ static unsigned char commit_data[] = { 0x3e, 0x0a, }; +#ifdef GIT_EXPERIMENTAL_SHA256 +static unsigned char commit_data_sha256[] = { + 0x74, 0x72, 0x65, 0x65, 0x20, 0x33, 0x34, 0x61, + 0x34, 0x38, 0x35, 0x34, 0x62, 0x35, 0x34, 0x32, + 0x36, 0x66, 0x39, 0x32, 0x34, 0x36, 0x30, 0x62, + 0x34, 0x61, 0x65, 0x33, 0x35, 0x65, 0x36, 0x64, + 0x37, 0x39, 0x37, 0x34, 0x36, 0x62, 0x65, 0x36, + 0x36, 0x63, 0x33, 0x38, 0x62, 0x66, 0x66, 0x64, + 0x36, 0x65, 0x66, 0x33, 0x62, 0x63, 0x34, 0x66, + 0x30, 0x35, 0x33, 0x65, 0x64, 0x37, 0x38, 0x61, + 0x33, 0x36, 0x62, 0x61, 0x34, 0x0a, 0x61, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x20, 0x41, 0x20, 0x55, + 0x20, 0x54, 0x68, 0x6f, 0x72, 0x20, 0x3c, 0x61, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x40, 0x65, 0x78, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, + 0x6d, 0x3e, 0x20, 0x31, 0x32, 0x32, 0x37, 0x38, + 0x31, 0x34, 0x32, 0x39, 0x37, 0x20, 0x2b, 0x30, + 0x30, 0x30, 0x30, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x74, 0x65, 0x72, 0x20, 0x43, 0x20, + 0x4f, 0x20, 0x4d, 0x69, 0x74, 0x74, 0x65, 0x72, + 0x20, 0x3c, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x74, 0x65, 0x72, 0x40, 0x65, 0x78, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x3e, + 0x20, 0x31, 0x32, 0x32, 0x37, 0x38, 0x31, 0x34, + 0x32, 0x39, 0x37, 0x20, 0x2b, 0x30, 0x30, 0x30, + 0x30, 0x0a, 0x0a, 0x41, 0x20, 0x6f, 0x6e, 0x65, + 0x2d, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x63, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x20, 0x73, 0x75, 0x6d, + 0x6d, 0x61, 0x72, 0x79, 0x0a, 0x0a, 0x54, 0x68, + 0x65, 0x20, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x20, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x2c, 0x20, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, + 0x20, 0x66, 0x75, 0x72, 0x74, 0x68, 0x65, 0x72, + 0x20, 0x65, 0x78, 0x70, 0x6c, 0x61, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x6f, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x70, 0x75, 0x72, 0x70, + 0x6f, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x73, 0x20, 0x69, 0x6e, 0x74, 0x72, 0x6f, + 0x64, 0x75, 0x63, 0x65, 0x64, 0x20, 0x62, 0x79, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x2e, 0x0a, 0x0a, 0x53, 0x69, + 0x67, 0x6e, 0x65, 0x64, 0x2d, 0x6f, 0x66, 0x2d, + 0x62, 0x79, 0x3a, 0x20, 0x41, 0x20, 0x55, 0x20, + 0x54, 0x68, 0x6f, 0x72, 0x20, 0x3c, 0x61, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x40, 0x65, 0x78, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, + 0x3e, 0x0a +}; +#endif + static object_data commit = { commit_bytes, sizeof(commit_bytes), "3d7f8a6af076c8c3f20071a8935cdbe8228594d1", + GIT_OID_SHA1, "commit", "test-objects/3d", "test-objects/3d/7f8a6af076c8c3f20071a8935cdbe8228594d1", @@ -123,7 +235,24 @@ static object_data commit = { sizeof(commit_data), }; -/* tree == dff2da90b254e1beb889d1f1f1288be1803782df */ +#ifdef GIT_EXPERIMENTAL_SHA256 +static object_data commit_sha256 = { + commit_bytes_sha256, + sizeof(commit_bytes_sha256), + "a2a430fb63b294f868af4ef6ccc9c3e8256e370859ce578a23837ac85337f562", + GIT_OID_SHA256, + "commit", + "test-objects/a2", + "test-objects/a2/a430fb63b294f868af4ef6ccc9c3e8256e370859ce578a23837ac85337f562", + commit_data_sha256, + sizeof(commit_data_sha256), +}; +#endif + +/* + * tree == dff2da90b254e1beb889d1f1f1288be1803782df (sha1) + * 34a4854b5426f92460b4ae35e6d79746be66c38bffd6ef3bc4f053ed78a36ba4 (sha256) + */ static unsigned char tree_bytes[] = { 0x78, 0x01, 0x2b, 0x29, 0x4a, 0x4d, 0x55, 0x30, 0x34, 0x32, 0x63, 0x30, 0x34, 0x30, 0x30, 0x33, @@ -163,10 +292,76 @@ static unsigned char tree_data[] = { 0xd8, 0xc2, 0xe4, 0x8c, 0x53, 0x91, }; +#ifdef GIT_EXPERIMENTAL_SHA256 +static unsigned char tree_bytes_sha256[] = { + 0x78, 0x01, 0x2b, 0x29, 0x4a, 0x4d, 0x55, 0x30, + 0x32, 0x32, 0x66, 0x30, 0x34, 0x30, 0x30, 0x33, + 0x31, 0x51, 0xc8, 0x48, 0xcd, 0xc9, 0xc9, 0xd7, + 0x2b, 0xa9, 0x28, 0x61, 0x28, 0x65, 0x3b, 0x7d, + 0xde, 0x27, 0x5c, 0xfb, 0xe5, 0x83, 0x2c, 0xf9, + 0xb7, 0xa6, 0x6b, 0xa2, 0x65, 0x7f, 0x6c, 0x5d, + 0xee, 0xab, 0x76, 0xa0, 0x9e, 0x49, 0xcd, 0xe3, + 0xe9, 0xcd, 0xa8, 0xf9, 0xf9, 0x5a, 0x50, 0x0d, + 0xf9, 0x79, 0xa9, 0x0c, 0x3e, 0xbc, 0x41, 0x17, + 0x1b, 0x8e, 0xc9, 0x32, 0x9e, 0x93, 0x9a, 0x78, + 0xef, 0xe8, 0xbb, 0x88, 0x0f, 0xa7, 0x9f, 0xc5, + 0x5f, 0x9d, 0x62, 0xbc, 0x6e, 0x05, 0xf3, 0xea, + 0x49, 0x95, 0xa9, 0x9e, 0xf6, 0xd7, 0xa1, 0x4a, + 0x8b, 0xf3, 0x73, 0x53, 0x19, 0x38, 0x6c, 0xb4, + 0xbb, 0x5d, 0xc2, 0x1c, 0x2e, 0x16, 0x3e, 0x5f, + 0x95, 0x56, 0xcd, 0x6d, 0xc4, 0x50, 0xc0, 0xf6, + 0xbd, 0xad, 0x50, 0xc0, 0xe8, 0xf5, 0x0e, 0x4d, + 0xc3, 0x33, 0xcb, 0xe6, 0x1c, 0x8c, 0x86, 0xaa, + 0x2d, 0x29, 0xcf, 0x67, 0xf8, 0x91, 0x14, 0xe7, + 0xfc, 0xf3, 0x81, 0xbf, 0x8a, 0xa6, 0x7c, 0xf9, + 0xd9, 0x7d, 0x3e, 0x85, 0x9b, 0x0f, 0x2d, 0xde, + 0xc0, 0x60, 0x9f, 0xe0, 0x38, 0xdb, 0xee, 0x42, + 0x16, 0x6b, 0x6f, 0x59, 0x4e, 0x37, 0x54, 0x69, + 0x55, 0x6a, 0x51, 0x3e, 0x83, 0xcb, 0xbc, 0xd9, + 0x95, 0x21, 0x0a, 0x67, 0xc5, 0xfe, 0x25, 0xac, + 0x0d, 0x9a, 0x71, 0x3e, 0x83, 0x5f, 0x74, 0xf9, + 0x59, 0xad, 0x93, 0x5b, 0xbc, 0x6e, 0x7d, 0x7f, + 0x6b, 0x77, 0x87, 0x97, 0xe3, 0x6e, 0x05, 0x00, + 0xba, 0xd1, 0x5f, 0x75 +}; + +static unsigned char tree_data_sha256[] = { + 0x31, 0x30, 0x30, 0x36, 0x34, 0x34, 0x20, 0x68, + 0x65, 0x6c, 0x6c, 0x6f, 0x2e, 0x74, 0x78, 0x74, + 0x00, 0x75, 0x06, 0xcb, 0xcf, 0x4c, 0x57, 0x2b, + 0xe9, 0xe0, 0x6a, 0x1f, 0xed, 0x35, 0xac, 0x5b, + 0x1d, 0xf8, 0xb5, 0xa7, 0x4d, 0x26, 0xc0, 0x7f, + 0x02, 0x26, 0x48, 0xe5, 0xd9, 0x5a, 0x9f, 0x6f, + 0x2a, 0x31, 0x30, 0x30, 0x36, 0x34, 0x34, 0x20, + 0x6f, 0x6e, 0x65, 0x00, 0x4c, 0x0d, 0x52, 0xd1, + 0x80, 0xc6, 0x1d, 0x01, 0xce, 0x1a, 0x91, 0xde, + 0xc5, 0xee, 0x58, 0xf0, 0xcb, 0xe6, 0x5f, 0xd5, + 0x94, 0x33, 0xae, 0xa8, 0x03, 0xab, 0x92, 0x79, + 0x65, 0x49, 0x3f, 0xd7, 0x31, 0x30, 0x30, 0x36, + 0x34, 0x34, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x00, + 0x08, 0x3c, 0x2b, 0x8b, 0x44, 0x56, 0x40, 0xd1, + 0x71, 0xe7, 0xaa, 0x66, 0x7b, 0x0b, 0x32, 0x00, + 0x70, 0x06, 0xf7, 0x86, 0x71, 0x10, 0x32, 0xeb, + 0xb8, 0x29, 0x31, 0xcc, 0xa6, 0x9c, 0xc1, 0x5b, + 0x31, 0x30, 0x30, 0x36, 0x34, 0x34, 0x20, 0x74, + 0x77, 0x6f, 0x00, 0xf8, 0x62, 0x5e, 0x43, 0xf9, + 0xe0, 0x4f, 0x24, 0x29, 0x1f, 0x77, 0xcd, 0xbe, + 0x4c, 0x71, 0xb3, 0xc2, 0xa3, 0xb0, 0x00, 0x3f, + 0x60, 0x41, 0x9b, 0x3e, 0xd0, 0x6a, 0x05, 0x8d, + 0x76, 0x6c, 0x8b, 0x31, 0x30, 0x30, 0x36, 0x34, + 0x34, 0x20, 0x7a, 0x65, 0x72, 0x6f, 0x00, 0x44, + 0x9e, 0x9b, 0x79, 0x54, 0x20, 0xcd, 0x16, 0xfe, + 0x60, 0xad, 0x52, 0x98, 0xcf, 0x68, 0x0f, 0x15, + 0xa7, 0xcd, 0x2a, 0xc9, 0xb4, 0x4a, 0xda, 0xf7, + 0xed, 0x3e, 0xdc, 0x0d, 0x08, 0xdd, 0x78 +}; +#endif + static object_data tree = { tree_bytes, sizeof(tree_bytes), "dff2da90b254e1beb889d1f1f1288be1803782df", + GIT_OID_SHA1, "tree", "test-objects/df", "test-objects/df/f2da90b254e1beb889d1f1f1288be1803782df", @@ -174,7 +369,24 @@ static object_data tree = { sizeof(tree_data), }; -/* tag == 09d373e1dfdc16b129ceec6dd649739911541e05 */ +#ifdef GIT_EXPERIMENTAL_SHA256 +static object_data tree_sha256 = { + tree_bytes_sha256, + sizeof(tree_bytes_sha256), + "34a4854b5426f92460b4ae35e6d79746be66c38bffd6ef3bc4f053ed78a36ba4", + GIT_OID_SHA256, + "tree", + "test-objects/34", + "test-objects/34/a4854b5426f92460b4ae35e6d79746be66c38bffd6ef3bc4f053ed78a36ba4", + tree_data_sha256, + sizeof(tree_data_sha256), +}; +#endif + +/* + * tag == 09d373e1dfdc16b129ceec6dd649739911541e05 (sha1) + * f535d7595d5d0e5e530b5deb34542c96491fea300a1318036b605306548cb225 (sha256) + */ static unsigned char tag_bytes[] = { 0x78, 0x01, 0x35, 0x4e, 0xcb, 0x0a, 0xc2, 0x40, 0x10, 0xf3, 0xbc, 0x5f, 0x31, 0x77, 0xa1, 0xec, @@ -222,10 +434,101 @@ static unsigned char tag_data[] = { 0x2e, 0x30, 0x2e, 0x31, 0x0a, }; +#ifdef GIT_EXPERIMENTAL_SHA256 +static unsigned char tag_bytes_sha256[] = { + 0x78, 0x01, 0x55, 0x8f, 0xd1, 0x4e, 0x84, 0x30, + 0x10, 0x45, 0x7d, 0xee, 0x57, 0xcc, 0xbb, 0x2e, + 0x81, 0x16, 0x68, 0x31, 0x1b, 0xa3, 0xf1, 0xd9, + 0xf8, 0xe0, 0xfa, 0x01, 0x43, 0x99, 0x42, 0x0d, + 0xb4, 0xa4, 0x14, 0xb3, 0xfc, 0xbd, 0xc5, 0xdd, + 0x4d, 0xb4, 0x69, 0xd2, 0x9b, 0xc9, 0xdc, 0x7b, + 0x6e, 0x23, 0xf6, 0x20, 0xa4, 0xba, 0xf3, 0xed, + 0x17, 0xe9, 0x08, 0xc8, 0xb1, 0x14, 0xb9, 0x69, + 0x6b, 0xd1, 0xf2, 0xa6, 0x34, 0xaa, 0x56, 0x68, + 0x4a, 0x32, 0xb5, 0xd6, 0xba, 0xd1, 0x82, 0x14, + 0xaf, 0x6a, 0x12, 0x32, 0x57, 0x55, 0xa3, 0xa9, + 0x92, 0x0a, 0xb9, 0x50, 0x42, 0xa2, 0x56, 0x95, + 0x10, 0xd2, 0x54, 0x35, 0x67, 0x71, 0x9b, 0x09, + 0xb4, 0x9f, 0x26, 0x1b, 0x59, 0x4c, 0xd9, 0xdf, + 0x79, 0x96, 0x67, 0xc5, 0x2e, 0x7b, 0x0a, 0xf0, + 0x0a, 0xef, 0xf0, 0x66, 0x63, 0x4c, 0xf2, 0x78, + 0x59, 0x4a, 0xf2, 0x99, 0xce, 0x38, 0xcd, 0x23, + 0x65, 0x69, 0xf2, 0x04, 0x05, 0xe7, 0x52, 0x15, + 0x25, 0x6f, 0x24, 0xdc, 0xe7, 0xe9, 0x30, 0x76, + 0x1a, 0xec, 0x02, 0xe9, 0xc6, 0x81, 0x60, 0x8f, + 0xbc, 0x56, 0x35, 0x3e, 0x40, 0xa0, 0x91, 0x70, + 0xa1, 0x1b, 0xe5, 0x0a, 0x86, 0x65, 0x9d, 0x26, + 0x0c, 0xdb, 0x6e, 0x25, 0x68, 0x7d, 0xb7, 0x81, + 0x37, 0xbf, 0xf6, 0x0b, 0x13, 0x26, 0x5a, 0x16, + 0xec, 0xe9, 0x21, 0xed, 0xbb, 0x88, 0xd6, 0x59, + 0xd7, 0x83, 0x59, 0x43, 0x02, 0x04, 0xa0, 0xf3, + 0x3c, 0xa2, 0xc3, 0x68, 0xbd, 0x63, 0x57, 0xd7, + 0xbc, 0x86, 0xd9, 0x27, 0xca, 0x2d, 0x64, 0x40, + 0xd7, 0x53, 0xaa, 0xe4, 0x62, 0xf0, 0xdd, 0xaa, + 0xa9, 0x83, 0x76, 0xfb, 0x13, 0x9f, 0x31, 0xf6, + 0x61, 0x7b, 0x47, 0xdd, 0xc1, 0x9b, 0x43, 0xbb, + 0x3d, 0xc2, 0x0b, 0x7c, 0xc2, 0x69, 0x48, 0x75, + 0x8f, 0xb8, 0xc6, 0xf4, 0xfe, 0xfb, 0x30, 0xfb, + 0x01, 0xc9, 0x32, 0x7d, 0xbb +}; + +static unsigned char tag_data_sha256[] = { + 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x61, + 0x32, 0x61, 0x34, 0x33, 0x30, 0x66, 0x62, 0x36, + 0x33, 0x62, 0x32, 0x39, 0x34, 0x66, 0x38, 0x36, + 0x38, 0x61, 0x66, 0x34, 0x65, 0x66, 0x36, 0x63, + 0x63, 0x63, 0x39, 0x63, 0x33, 0x65, 0x38, 0x32, + 0x35, 0x36, 0x65, 0x33, 0x37, 0x30, 0x38, 0x35, + 0x39, 0x63, 0x65, 0x35, 0x37, 0x38, 0x61, 0x32, + 0x33, 0x38, 0x33, 0x37, 0x61, 0x63, 0x38, 0x35, + 0x33, 0x33, 0x37, 0x66, 0x35, 0x36, 0x32, 0x0a, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x63, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x0a, 0x74, 0x61, 0x67, 0x20, + 0x76, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x0a, 0x74, + 0x61, 0x67, 0x67, 0x65, 0x72, 0x20, 0x43, 0x20, + 0x4f, 0x20, 0x4d, 0x69, 0x74, 0x74, 0x65, 0x72, + 0x20, 0x3c, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x74, 0x65, 0x72, 0x40, 0x65, 0x78, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x3e, + 0x20, 0x31, 0x32, 0x32, 0x37, 0x38, 0x31, 0x34, + 0x32, 0x39, 0x37, 0x20, 0x2b, 0x30, 0x30, 0x30, + 0x30, 0x0a, 0x0a, 0x54, 0x68, 0x69, 0x73, 0x20, + 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, + 0x61, 0x67, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x72, 0x65, + 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x76, 0x30, + 0x2e, 0x30, 0x2e, 0x31, 0x0a, 0x20, 0x63, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x20, 0x73, 0x75, 0x6d, + 0x6d, 0x61, 0x72, 0x79, 0x0a, 0x0a, 0x54, 0x68, + 0x65, 0x20, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x20, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x2c, 0x20, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, + 0x20, 0x66, 0x75, 0x72, 0x74, 0x68, 0x65, 0x72, + 0x20, 0x65, 0x78, 0x70, 0x6c, 0x61, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x6f, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x70, 0x75, 0x72, 0x70, + 0x6f, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x73, 0x20, 0x69, 0x6e, 0x74, 0x72, 0x6f, + 0x64, 0x75, 0x63, 0x65, 0x64, 0x20, 0x62, 0x79, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x2e, 0x0a, 0x0a, 0x53, 0x69, + 0x67, 0x6e, 0x65, 0x64, 0x2d, 0x6f, 0x66, 0x2d, + 0x62, 0x79, 0x3a, 0x20, 0x41, 0x20, 0x55, 0x20, + 0x54, 0x68, 0x6f, 0x72, 0x20, 0x3c, 0x61, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x40, 0x65, 0x78, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, + 0x3e, 0x0a +}; +#endif + static object_data tag = { tag_bytes, sizeof(tag_bytes), "09d373e1dfdc16b129ceec6dd649739911541e05", + GIT_OID_SHA1, "tag", "test-objects/09", "test-objects/09/d373e1dfdc16b129ceec6dd649739911541e05", @@ -233,7 +536,24 @@ static object_data tag = { sizeof(tag_data), }; -/* zero == e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 */ +#ifdef GIT_EXPERIMENTAL_SHA256 +static object_data tag_sha256 = { + tag_bytes_sha256, + sizeof(tag_bytes_sha256), + "f535d7595d5d0e5e530b5deb34542c96491fea300a1318036b605306548cb225", + GIT_OID_SHA256, + "tag", + "test-objects/f5", + "test-objects/f5/35d7595d5d0e5e530b5deb34542c96491fea300a1318036b605306548cb225", + tag_data_sha256, + sizeof(tag_data_sha256), +}; +#endif + +/* + * zero == e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 (sha1) + * 473a0f4c3be8a93681a267e3b1e9a7dcda1185436fe141f7749120a303721813 (sha256) + */ static unsigned char zero_bytes[] = { 0x78, 0x01, 0x4b, 0xca, 0xc9, 0x4f, 0x52, 0x30, 0x60, 0x00, 0x00, 0x09, 0xb0, 0x01, 0xf0, @@ -247,6 +567,7 @@ static object_data zero = { zero_bytes, sizeof(zero_bytes), "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", + GIT_OID_SHA1, "blob", "test-objects/e6", "test-objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391", @@ -254,7 +575,24 @@ static object_data zero = { 0, }; -/* two == 78981922613b2afb6025042ff6bd878ac1994e85 */ +#ifdef GIT_EXPERIMENTAL_SHA256 +static object_data zero_sha256 = { + zero_bytes, + sizeof(zero_bytes), + "473a0f4c3be8a93681a267e3b1e9a7dcda1185436fe141f7749120a303721813", + GIT_OID_SHA256, + "blob", + "test-objects/47", + "test-objects/47/3a0f4c3be8a93681a267e3b1e9a7dcda1185436fe141f7749120a303721813", + zero_data, + 0, +}; +#endif + +/* + * two == 78981922613b2afb6025042ff6bd878ac1994e85 (sha1) + * f8625e43f9e04f24291f77cdbe4c71b3c2a3b0003f60419b3ed06a058d766c8b (sha256) + */ static unsigned char two_bytes[] = { 0x78, 0x01, 0x4b, 0xca, 0xc9, 0x4f, 0x52, 0x30, 0x62, 0x48, 0xe4, 0x02, 0x00, 0x0e, 0x64, 0x02, @@ -269,6 +607,7 @@ static object_data two = { two_bytes, sizeof(two_bytes), "78981922613b2afb6025042ff6bd878ac1994e85", + GIT_OID_SHA1, "blob", "test-objects/78", "test-objects/78/981922613b2afb6025042ff6bd878ac1994e85", @@ -276,7 +615,24 @@ static object_data two = { sizeof(two_data), }; -/* some == fd8430bc864cfcd5f10e5590f8a447e01b942bfe */ +#ifdef GIT_EXPERIMENTAL_SHA256 +static object_data two_sha256 = { + two_bytes, + sizeof(two_bytes), + "f8625e43f9e04f24291f77cdbe4c71b3c2a3b0003f60419b3ed06a058d766c8b", + GIT_OID_SHA256, + "blob", + "test-objects/f8", + "test-objects/f8/625e43f9e04f24291f77cdbe4c71b3c2a3b0003f60419b3ed06a058d766c8b", + two_data, + sizeof(two_data), +}; +#endif + +/* + * some == fd8430bc864cfcd5f10e5590f8a447e01b942bfe (sha1) + * 083c2b8b445640d171e7aa667b0b32007006f786711032ebb82931cca69cc15b (sha256) + */ static unsigned char some_bytes[] = { 0x78, 0x01, 0x7d, 0x54, 0xc1, 0x4e, 0xe3, 0x30, 0x10, 0xdd, 0x33, 0x5f, 0x31, 0xc7, 0x5d, 0x94, @@ -514,9 +870,24 @@ static object_data some = { some_bytes, sizeof(some_bytes), "fd8430bc864cfcd5f10e5590f8a447e01b942bfe", + GIT_OID_SHA1, "blob", "test-objects/fd", "test-objects/fd/8430bc864cfcd5f10e5590f8a447e01b942bfe", some_data, sizeof(some_data), }; + +#ifdef GIT_EXPERIMENTAL_SHA256 +static object_data some_sha256 = { + some_bytes, + sizeof(some_bytes), + "083c2b8b445640d171e7aa667b0b32007006f786711032ebb82931cca69cc15b", + GIT_OID_SHA256, + "blob", + "test-objects/08", + "test-objects/08/3c2b8b445640d171e7aa667b0b32007006f786711032ebb82931cca69cc15b", + some_data, + sizeof(some_data), +}; +#endif diff --git a/tests/libgit2/odb/mixed.c b/tests/libgit2/odb/mixed.c index 87e945c83..19e6dcebf 100644 --- a/tests/libgit2/odb/mixed.c +++ b/tests/libgit2/odb/mixed.c @@ -5,7 +5,7 @@ static git_odb *_odb; void test_odb_mixed__initialize(void) { - cl_git_pass(git_odb_open(&_odb, cl_fixture("duplicate.git/objects"))); + cl_git_pass(git_odb__open(&_odb, cl_fixture("duplicate.git/objects"), NULL)); } void test_odb_mixed__cleanup(void) @@ -20,13 +20,13 @@ void test_odb_mixed__dup_oid(void) { git_oid oid; git_odb_object *obj; - cl_git_pass(git_oid_fromstr(&oid, hex)); - cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, GIT_OID_HEXSZ)); + cl_git_pass(git_oid__fromstr(&oid, hex, GIT_OID_SHA1)); + cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, GIT_OID_SHA1_HEXSIZE)); git_odb_object_free(obj); - cl_git_pass(git_odb_exists_prefix(NULL, _odb, &oid, GIT_OID_HEXSZ)); + cl_git_pass(git_odb_exists_prefix(NULL, _odb, &oid, GIT_OID_SHA1_HEXSIZE)); - cl_git_pass(git_oid_fromstrn(&oid, short_hex, sizeof(short_hex) - 1)); + cl_git_pass(git_oid__fromstrn(&oid, short_hex, sizeof(short_hex) - 1, GIT_OID_SHA1)); cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, sizeof(short_hex) - 1)); git_odb_object_free(obj); @@ -48,63 +48,63 @@ void test_odb_mixed__dup_oid_prefix_0(void) { /* ambiguous in the same pack file */ strncpy(hex, "dea509d0", sizeof(hex)); - cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex))); + cl_git_pass(git_oid__fromstrn(&oid, hex, strlen(hex), GIT_OID_SHA1)); cl_assert_equal_i( GIT_EAMBIGUOUS, git_odb_read_prefix(&obj, _odb, &oid, strlen(hex))); cl_assert_equal_i( GIT_EAMBIGUOUS, git_odb_exists_prefix(&found, _odb, &oid, strlen(hex))); strncpy(hex, "dea509d09", sizeof(hex)); - cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex))); + cl_git_pass(git_oid__fromstrn(&oid, hex, strlen(hex), GIT_OID_SHA1)); cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, strlen(hex))); cl_git_pass(git_odb_exists_prefix(&found, _odb, &oid, strlen(hex))); cl_assert_equal_oid(&found, git_odb_object_id(obj)); git_odb_object_free(obj); strncpy(hex, "dea509d0b", sizeof(hex)); - cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex))); + cl_git_pass(git_oid__fromstrn(&oid, hex, strlen(hex), GIT_OID_SHA1)); cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, strlen(hex))); git_odb_object_free(obj); /* ambiguous in different pack files */ strncpy(hex, "81b5bff5", sizeof(hex)); - cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex))); + cl_git_pass(git_oid__fromstrn(&oid, hex, strlen(hex), GIT_OID_SHA1)); cl_assert_equal_i( GIT_EAMBIGUOUS, git_odb_read_prefix(&obj, _odb, &oid, strlen(hex))); cl_assert_equal_i( GIT_EAMBIGUOUS, git_odb_exists_prefix(&found, _odb, &oid, strlen(hex))); strncpy(hex, "81b5bff5b", sizeof(hex)); - cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex))); + cl_git_pass(git_oid__fromstrn(&oid, hex, strlen(hex), GIT_OID_SHA1)); cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, strlen(hex))); cl_git_pass(git_odb_exists_prefix(&found, _odb, &oid, strlen(hex))); cl_assert_equal_oid(&found, git_odb_object_id(obj)); git_odb_object_free(obj); strncpy(hex, "81b5bff5f", sizeof(hex)); - cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex))); + cl_git_pass(git_oid__fromstrn(&oid, hex, strlen(hex), GIT_OID_SHA1)); cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, strlen(hex))); git_odb_object_free(obj); /* ambiguous in pack file and loose */ strncpy(hex, "0ddeaded", sizeof(hex)); - cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex))); + cl_git_pass(git_oid__fromstrn(&oid, hex, strlen(hex), GIT_OID_SHA1)); cl_assert_equal_i( GIT_EAMBIGUOUS, git_odb_read_prefix(&obj, _odb, &oid, strlen(hex))); cl_assert_equal_i( GIT_EAMBIGUOUS, git_odb_exists_prefix(&found, _odb, &oid, strlen(hex))); strncpy(hex, "0ddeaded9", sizeof(hex)); - cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex))); + cl_git_pass(git_oid__fromstrn(&oid, hex, strlen(hex), GIT_OID_SHA1)); cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, strlen(hex))); cl_git_pass(git_odb_exists_prefix(&found, _odb, &oid, strlen(hex))); cl_assert_equal_oid(&found, git_odb_object_id(obj)); git_odb_object_free(obj); strncpy(hex, "0ddeadede", sizeof(hex)); - cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex))); + cl_git_pass(git_oid__fromstrn(&oid, hex, strlen(hex), GIT_OID_SHA1)); cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, strlen(hex))); git_odb_object_free(obj); } @@ -170,7 +170,7 @@ static void setup_prefix_query( size_t len = strlen(expand_id_test_data[i].lookup_id); - git_oid_fromstrn(&id->id, expand_id_test_data[i].lookup_id, len); + git_oid__fromstrn(&id->id, expand_id_test_data[i].lookup_id, len, GIT_OID_SHA1); id->length = (unsigned short)len; id->type = expand_id_test_data[i].expected_type; } @@ -186,13 +186,13 @@ static void assert_found_objects(git_odb_expand_id *ids) num = ARRAY_SIZE(expand_id_test_data); for (i = 0; i < num; i++) { - git_oid expected_id = {{0}}; + git_oid expected_id = GIT_OID_SHA1_ZERO; size_t expected_len = 0; git_object_t expected_type = 0; if (expand_id_test_data[i].expected_id) { - git_oid_fromstr(&expected_id, expand_id_test_data[i].expected_id); - expected_len = GIT_OID_HEXSZ; + git_oid__fromstr(&expected_id, expand_id_test_data[i].expected_id, GIT_OID_SHA1); + expected_len = GIT_OID_SHA1_HEXSIZE; expected_type = expand_id_test_data[i].expected_type; } @@ -204,7 +204,7 @@ static void assert_found_objects(git_odb_expand_id *ids) static void assert_notfound_objects(git_odb_expand_id *ids) { - git_oid expected_id = {{0}}; + git_oid expected_id = GIT_OID_SHA1_ZERO; size_t num, i; num = ARRAY_SIZE(expand_id_test_data); diff --git a/tests/libgit2/odb/open.c b/tests/libgit2/odb/open.c new file mode 100644 index 000000000..395406d0f --- /dev/null +++ b/tests/libgit2/odb/open.c @@ -0,0 +1,34 @@ +#include "clar_libgit2.h" + +void test_odb_open__initialize(void) +{ + cl_fixture_sandbox("testrepo.git"); +} + +void test_odb_open__cleanup(void) +{ + cl_fixture_cleanup("testrepo.git"); +} + +void test_odb_open__exists(void) +{ + git_odb *odb; + git_oid one, two; + +#ifdef GIT_EXPERIMENTAL_SHA256 + git_odb_options opts = GIT_ODB_OPTIONS_INIT; + + cl_git_pass(git_odb_open(&odb, "testrepo.git/objects", &opts)); + cl_git_pass(git_oid_fromstr(&one, "1385f264afb75a56a5bec74243be9b367ba4ca08", GIT_OID_SHA1)); + cl_git_pass(git_oid_fromstr(&two, "00112233445566778899aabbccddeeff00112233", GIT_OID_SHA1)); +#else + cl_git_pass(git_odb_open(&odb, "testrepo.git/objects")); + cl_git_pass(git_oid_fromstr(&one, "1385f264afb75a56a5bec74243be9b367ba4ca08")); + cl_git_pass(git_oid_fromstr(&two, "00112233445566778899aabbccddeeff00112233")); +#endif + + cl_assert(git_odb_exists(odb, &one)); + cl_assert(!git_odb_exists(odb, &two)); + + git_odb_free(odb); +} diff --git a/tests/libgit2/odb/pack_data_256.h b/tests/libgit2/odb/pack_data_256.h new file mode 100644 index 000000000..b63188227 --- /dev/null +++ b/tests/libgit2/odb/pack_data_256.h @@ -0,0 +1,154 @@ +#ifdef GIT_EXPERIMENTAL_SHA256 + +static const char *packed_objects_256[] = { + "99f3b405443221141eb0fd1e0cca5d355f893983749b7fb455769fba434e7945", + "d0fc7f52dc42358506e7f3f3be72f5271994abb104b9397ab3e19bb42361504d", + "86e228d9904af64586e9a8378005ba654681ff5be3c43ca930bf6b1f28d4395f", + "652412419a24ba62a1d897f40aeb80eecbf873797b04a1bbb8d71918653ef65b", + "ad90f638cb67720b20b904478471504acebacc7bb36e5dcad3e882acec496fed", + "4d46d9719e425ef2dfb5bfba098d0b62e21b2b92d0731892eef70db0870e3744", + "80ec1e36b983e68664e8357c538cd35b30638bb0cb99626f906d145e2d2e2558", + "e8bbf40ee280bc43b33c04df2250903b75e92f2497e91759cf1cad753c23be6c", + "8864b5746d7c5780083bb98449a3f5bf78d8281e8c5e3fd12a8ccd9103eb3a1f", + "083c2b8b445640d171e7aa667b0b32007006f786711032ebb82931cca69cc15b", + "5c8bea399f78d3d6a037a41cee2e763d00024180b66f2ec738d443b6a3dd7081", + "281c36286eab5e534f1c2121a4cf2cd48a32b3773a3e78df500bed3f3c9747f3", + "c9dc53358a0d83bee1caae40ee81d752abf4962a9f206702e24a447b766b5bd7", + "fafc05a1d0b7614ba32f428eb52f3439ffbfed9a817e5ae069364cfc3fa3e4d4", + "25a4efebb38c55b8f2309ce5e3116b2b9287239952cc2fa174074e05c6e5875a", + "c223f1b579bad18635efdeffa7a8ff40567d03fa427e08bb90d9878f958d8021", + "8a0042d434a2f8a2e8d47caa4eb454f388752fb3fe71150c1cea12e807cfdf1c", + "d79e913b4137117b7f8fc2a8d184373f657d6f71bbeaca0fe83b7757ce486108", + "375f69d3d41e36d6904bfa86221690ec49de2a030664a362abaf86c426f9f7e0", + "22b6705b86e4aa9120eff203af24709d483698d9f78695e86e82de121784b570", + "4516b0e63349c81abc6584cb11ce84ab8ba38b105f9de39d0d0a1455dba2478d", + "c2b535bfc3501f0b4e179d5d6f0e2cea613940fa3813be5923db7e71e190849f", + "aa793f0e9d9d746eba8a7a60cb4981f7e24ce9691910350d7df9b9e94c7567b9", + "890bb959ac8c20db603bf083bc82f55f9f42b6dca6581d941d0b361188abae3b", + "bfc0ee6fe04854c11011539f38cc6b9b73e0c445bac2008de2fb877123efc2e3", + "5ba7253f47d390ee2c7c7afe8fd9a963a7a2674bbdadeb9a927665c9246306c4", + "79bc735b91f8dfa9379d1d6c21e2d519ac1bf0d04d48534864c9ff571df5297d", + "f362826c827aa3bcbeb3ff8b71bba08d7440b89ab53fe95d61b8922d01f46e28", + "4a1b9c078e7bb20759a2d75e3a4b96827c851446c0261750b96aa5f286efe378", + "2e2aa456dbbb8889923eb6713672427854020298a764967c50235a9a76d7ce4b", + "97b0e3661fa0caa6200c50381233f8320b907540ceb9d17ac94fedc66fd093c2", + "ade7d297ede7bb58008da582de1253f0a55cb76e82d1cd376f82ccf97f70bced", + "3315093132a8f28bd202c0a9562d04eebea4943dcd1e1c754341b0389722042f", + "6fae137ba81d0d81c2a85759b99322e7ea8103bd7c8b85be3163b7e91e18c125", + "f8b45f792840019909fd35f9dcb98082b3bc39373268d467e1b00f1da5ac71e5", + "d2ab425d6092770366bc3dff5276e3a869221bc7b6d22e99c089d556e7eb8331", + "4dd37b9df07bcc7b45ce72a44e3f5fcaf5f0a9a5f3148963714eac4c99a60388", + "8c53c0f9f0972a1c77e40549170b9ae51d365c200ffc4cb220628c5bce3dd0b2", + "11d0463a82345c2512bd704dd00211aefb7d5b8590ca92809122fd09486a9f06", + "1ab4fa663d22416f45cb1a007d767a58d0abf5255bf86f888393dae637b37c3b", + "345d2fbf1d306c7ea46a05f497793308357e9e17ab0e866446d2b9894378ddce", + "304352ddad641770fcc94ee4d9f957cde7aaf4c107dbf8b5ba14d543640bf7dd", + "cfdd565f4cbc315760c287d57714852e1a4894eef9c715332fd556f2e114a9f1", + "d6d2e87e6de8690efd26b8c5b58de28dcb3c9bd2b7659eccf34468d71a7a4478", + "aa61d4adf622265ec814c1a97198d2bcd3f58fb08989cb9beda32a4d0aab6697", + "40799f33b8cd9ca41f36a2f89d8ac8550537ad01dfb21fbc76f01eeb62f512d4", + "faa7ca59426e17f6b34fa407d06cd634faaabeb4abe26df12296e05a17c98eef", + "1f6ea2cab887a2ff4bb1557a36dd6bac9931ef1f36794ddd22b4b7b7276051fb", + "b38a7a2ee69d55f021efa91caf59e23bccdaf6b8a9c3f83acd978aa177587537", + "f66691f32eb9b23a029b43251bfa994d16481fe97903057e121b76e4e78f6ff4", + "afe1fad6f6b22eea530ff7b373d6b9b787b39792f720e6fcd0692ba6ef99e02f", + "b71ee6c8837efa5b3ba3361f88c321d391ac05f41d5b2506cad39319e80716e4", + "e207a266e228414023223530eb77c64b10f2f5124f3354deb45aff04c1db98b9", + "696503760a18787240ba52ad1abec3be6517bb802238e9469b3a8999cbd6432c", + "c30d06fd49797e3135652d654db0de122dd83f8400df1c7a0e95ca3720defb0d", + "8a9b600a21987e6ffddbad745f38c115797eacef9117043bd9d2da4835ee3cc4", + "d509fa76ff5944e25f48c2476736b6239a53f0463cba6ebc488464d087951951", + "3e00d8cae2726dc33879adf876b30c306f50e7a85b15c8add4a27f84d88616d7", + "ce55f9f5ab1d799a9ffaa839539af196d13f35677b3d0761b0fe034e764f8d07", + "84005e38a65f4115d5c94790010dc57e1a3297f4aa89744f5927f208af758bd0", + "75b0ed5f4a2d5c810f34d867dbca51db6a596d4739abfaf24fcc0f05d99097a8", + "3eab74a6894d790767f3d92615a6887dcccaffa9e48fdd2ce482b5f17efcf9b9", + "8e61988c998c96a131cfe72225fce43e555bec4e590fa8c239373172a9d485ce", + "5f45a18f90f2934e7c7985d05b2b5b3584886fd057c9202f26f562d6c3080038", + "7609c608c1097270356a6fe336a8756ff124d4a9c2e941bba26a6e8c3becdeb1", + "81ba4e67aa59ccb078e3dc9ff3075f50084ec1696bd867e8e4284fcfc34fe3cf", + "3b1b991ae70d1f5388ad16b63d2285e99ada7a618c6f5d01e50a6d4b33c4767d", + "ac49410f64fad10760838866a40107573e42c86908c83ece433d64b7a8b57f7f", + "72c472319cf7d5d59bf9fea9e90b9785d7ab39340003fbc68619c11a9e583c2f", + "3a0cd33a47fcd0c7b8f8c1d407aaa53f648e25f2ffe2533a7e9c09c3d1b9da75", + "bf409f1aa76256282ebf1a7cc6c9f4220be9ffc47b2cc42248fcc5cbb67bce1f", + "13c8c9dae9fa63b1ec48b8abb12312fc8df61b9414678f504fa68164a48eef28", + "078baf54914fab56842798c90fec863f15f67a22041e8aa54a88c43f059da050", + "41c166c241a4e878f444932a193501e12ab38ba0634747291df70e619dccee1c", + "9db520a5a88c7d75b86a4faa1ce9010edf38af922f400c69a4a93aef69e25c4c", + "edf6e0dbfaf8a7ad89b05b5768981eeedd7a2bda4b1d0fae07aa2a9d49bb39df", + "ec1866b39026366e69ab8e167c15312c27f5eda4c0afdf9367ac3d76f56bf8e7", + "695bdb545f636d454b4825effd29db96c46d81772dda6c104f97dffe2ec509f1", + "07c31b4be5f3ec8f82c7ad6c91cbdf07ae876bb73041903d64fe8bac64bbcb6e", + "06665948a581e547ac1dc883b35bab54682fc311f7a87d5563a76501ecba55fc", + "fa6a2b7e588e57115d2772c0d5250d886757404fc510a5956be8de4926e94c01", + "28aec9a4450d9de98db98a021f97026bf12f1328f66e53319669eb5adce5ed3e", + "290d84a2cf108c074d3764ca8dc56e1215a5a7482837f098dff7a55e23d89d5f", + "ed10f9520d5f0d6bbd9c467ed83a239df0cba94ae9031602e02f6ad6256c459e", + "ad05c66a177f844f8239a1d186a1f803a4daa6286c959538838e222bc6337dc9", + "88fecc715077807bd7ee9e6a1dff65fde000379e0bf2a15cc2404469cef4c82b", + "bcc4fa242e55c5e08f64900407dca1cf2451806830905be616f339bf7a5580aa", + "4a4ebb837e3c9883f35d0ecdc26d4bc76a0f665568b08f3e967096f2fd3fa537", + "9abb7801e72353060a1490ffa3331674d6882558e7d6458de397b4b00d31ff8c", + "466cdfec4c74f3ed4fe53165e468a52df5dff9c6533ec433cdf235a73e099d32", + "8a1e1a6cc00519c4df8ce404c987751446fa299662308622cb63576fb52996d7", + "e5ea38108d603a6ed8dbb0b8455abe6d971f2d60920207e67ba646d267ece305", + "97e00ba4c8028ea91e7131c8c7596227cd03d3d2d14ed2d179fe0f305ebbca39", + "807faa3586b7f1aff2797a7c39c135b0196647c9ae7ee8843322accc960b2f22", + "b9134c331629e9cb29d1bbc03904d911a942b451e087543fc16deb0116391297", + "23cb97c200205dc84109c248be5bd719c23bdab52b52c51ec92fef9a48790833", + "b6e8427e3afe1cf0095d0f5aeca0642c4fb12d4e529f62e8264b6c4db72f04b4", + "92128dfb792caea934f5218807ec993867b0c8487a3de69ebac33e067f64d38a", + "a13ecbc514b571721a9a1c92af7f89d473a5fe13228904f8d17368e71f273ea1", + "3f5dca26a2f512d6681ce1957b8afba5e031bf63d52fd52d8f57093bf92391a4", + "1aa24b7ebd910f39a676f2ccab8e9a79f14842c20b55ed18e3dc297bdbaca279", + "1e0ce38d00e8f3e613febc0f8b275e0fd7fbef8af293fd62698be46dfbbc937d", + "dd9b1d5ca653752cef167e034324198971ab6f2f38f3db9db571cb2985759f00", + "efc4b8fd4b0b2586fce256b107ee2a052d11d26f99d85ce0478c3d49d1b2186b", + "da38f65b32fb03ce332e0c4238edae0a733e4cd793d849522bb4e0bdd0af608c", + "bf66badfda7b5d2157db65c5310cfdc4e904d7d5da57ac5abe17542de612f856", + "2c0f52f9ae1f34f280dfc1c755cbfaf2b9968fd3bab1f1eb16d3ac0fafd71940", + "165ec90aa4190bbe12ee415b294fd6d204c64afcf1ca64dd815782872b24ea26", + "cc3d272d457c7e26c5d611923841511a1766bcd58e5be66433698627e6fb3f9d", + "d970d1a6296d149bfb8283b8b4a9a6f7e9ee320c5d46a5ef216e10400df2d281", + "bdc530e0b98dd736cd812408eeed9aa0d393bbd0630b355eb7601e61f0dbc7c4", + "94db24aca3f8e07f481744f62633730feb4fc47605280381a08be510ae971ffe", + "151c7527acc5b731199a03a932ae374331e16e5ae29256e98cb652f37669889b", + "ac88849a26c126b03fc6fcb17cb23ec563e87a5f63b7afe800ad0f436128ce98", + "26a2dac21f8f0939566570e48f7f4fcf89239c2746ef8d3dbf31d179c691808f", + "619f24a7f37f8ca922c83b3a1b9a384eb6a444ff3a2a52c712f3c60dde6f24fb", + "5329dd2fd8557be5ad06b57882cf42e23d767cdc8a4b25e464fdb00890649e07", + "fff5cbc10ffea865d69aba64082ae17479c522e8e0305e678469749282bf0a18", + "d0c992aae9cde855b17ac826234a73255ecb09534cdcfa633d90640f6a4324d9", + "6129f1672465ee7b9e2edef53fbf3846ab5d06e8e6a1d7fb51e31666a8b411f8", + "0a8c0add81b065b97451f7b47a9935f0e240251c5f90a89ced885cb7d4efc2ba", + "471fa4fc2da467dd94e57babb1912bbdb5e40b96c8129d46fc709c0bfc009bca", + "23cea2b49eed4993c5b92a9d5f0b82efe4fae3837ea707d921de645d04479015", + "c85e35eec23dea4089aee7a2dc7f6d937ad7e13c66bdbd7eef37bd6336418609", + "a0f3dac8fa0e22dcf356aecbbdf79440715687c1053bc59b83354f276d688ceb", + "1cfb8ae71e9e576d1b16b7bd1a62156d0641c6e51f5d76877be6de4f26410623" +}; + +static const char *loose_objects_256[] = { + "96c18f0297e38d01f4b2dacddea4259aea6b2961eb0822bd2c0c3f6029030045", + "aea29dc305d40e362df25c3fdeed5502fd56b182af01b7740d297a24459333c5", + "73b4f3c4f3182e6c8dd2c98aeb2c7811556538e7673e4b325307c71685fbf5b6", + "901505c3355518bee35475c5d3f23bac1dded688b2bd314cc32b7f157e100724", + "4bc142808884e472ee6cc331b132e66ef18f564d41efb055804ec1dd28efb3f5", + "7e4633ae1b0e83503dbea4417f9d5ccaf22b877c5a4522b6d1d2b16090ee2f6f", + "473a0f4c3be8a93681a267e3b1e9a7dcda1185436fe141f7749120a303721813", + "7030f925768d9beb65654ab8f436e3ca0a82b25eddefd237bf5a26a0441c2aa7", + "cb282e7c15fd8aeb2265cd621f5a228cb33dc84192980ca426cf9ab2a48cb9f0", + "33e415b835a670bb5c3c760efa0433ac0cbd2d44679f68f2df3a9ae7014cf2a8", + "8155958bbda08eed88c8ac908dc44452ed38911cffa54ccc06076f30a1ffb1bf", + "1b4b74772bd83ff28bf44cda9be93f4afc2279623bb5b36c9194a660b7623c24", + "f31459efb9367c5a19c9dd24c75107423d5773066922ea5e55eaeb6490979562", + "6d5fd291bb0f67444e99ab492f1bf1fcdf5dca09dab24cf331e05111b4cfc1a3", + "b83624f6ac0995273c0034a7ab8c68929bdc91b69ad54ef94979b93eba3f6022", + "61489e9e831f1d9001084d39b79f964c293db8620d679ea3596673c8a326446e", + "abee32b3339d1566d75613ea61f40c14bdfc5b101b60fde4f44b58dd06667640", + "a4813ef6708e6011e8187224297e83e4a285f58bf5eabb1db270351388603c95", + "43e084a4599ca42c476919917e3db8fde0045ee66305fd5e634b0c793c536a1b" +}; + +#endif diff --git a/tests/libgit2/odb/pack_data_one256.h b/tests/libgit2/odb/pack_data_one256.h new file mode 100644 index 000000000..98a874798 --- /dev/null +++ b/tests/libgit2/odb/pack_data_one256.h @@ -0,0 +1,21 @@ +/* Just a few to make sure it's working, the rest is tested already */ +#ifdef GIT_EXPERIMENTAL_SHA256 +static const char *packed_objects_one256[] = { + "ea926306b1bab6d3f25f45609907eb6dff91a1460b25e63bf4a0494c70e7a269", + "d048ba2ef4fafa502a44cbc1a50cd58359b9bc243b84a08f541a08ca5f621137", + "a66bda0109d2b3c9bc87970da81bd91076b5f871febbc860f09ae997668b6800", + "3609a41c0506fe19d01fb8b4729923362675f191fe5f63fab3111ef804c48fdf", + "22b6705b86e4aa9120eff203af24709d483698d9f78695e86e82de121784b570", + "6f11d93bfb269ee8c7a506178f60c430abfac5d424acfd9c0b0b27b98e6ab49b", + "0aefd477d9e5b3f8d708a3cf6d78be6b670dfa2e2ec41244634f3b8f115d8e04", + "580474d948cd2ebd2e5ce7a5b81b872d87ba4639c1ac4c0fa7a11a8eddf9827c", + "0636b4292bfdd7274a977cb6f8b2ded8f315ea1bcd8dbedfca37964c2ed3d085", + "19fb1c78b11f0f8bda658d6fa6cc63c0b573c0f6760ee5a9c2df6ce2cde00c5c", + "7f2f7afccb317bb3fdd28555f126846dc4eebe5d9ae7b8d8a1456e8ff85422ce", + "4066249c68b0d3c8b39ebe02c9188935900465acad02a49269710f56720fa58e", + "a560d1fa1edf114f57b402e16d662c17b1e3b7e8601ff7dcea6615ba7f1e48ef", + "58923faa87c7d559d308a114ec2b164e5d6046c889420ed1def6eef2d55106a2", + "753ddabab8ae9c1e733cda15e8e3c83dd43f5a2d939ae32cc3b30b0be1e91f96", + "46333d32b3801cf11d9f80b557245c9e32b0e05deca61dae968914fde159f0e5" +}; +#endif diff --git a/tests/libgit2/odb/packed.c b/tests/libgit2/odb/packed.c index 3d502ed6d..b41041fc1 100644 --- a/tests/libgit2/odb/packed.c +++ b/tests/libgit2/odb/packed.c @@ -6,7 +6,7 @@ static git_odb *_odb; void test_odb_packed__initialize(void) { - cl_git_pass(git_odb_open(&_odb, cl_fixture("testrepo.git/objects"))); + cl_git_pass(git_odb__open(&_odb, cl_fixture("testrepo.git/objects"), NULL)); } void test_odb_packed__cleanup(void) @@ -23,7 +23,7 @@ void test_odb_packed__mass_read(void) git_oid id; git_odb_object *obj; - cl_git_pass(git_oid_fromstr(&id, packed_objects[i])); + cl_git_pass(git_oid__fromstr(&id, packed_objects[i], GIT_OID_SHA1)); cl_assert(git_odb_exists(_odb, &id) == 1); cl_git_pass(git_odb_read(&obj, _odb, &id)); @@ -41,7 +41,7 @@ void test_odb_packed__read_header_0(void) size_t len; git_object_t type; - cl_git_pass(git_oid_fromstr(&id, packed_objects[i])); + cl_git_pass(git_oid__fromstr(&id, packed_objects[i], GIT_OID_SHA1)); cl_git_pass(git_odb_read(&obj, _odb, &id)); cl_git_pass(git_odb_read_header(&len, &type, _odb, &id)); @@ -63,7 +63,7 @@ void test_odb_packed__read_header_1(void) size_t len; git_object_t type; - cl_git_pass(git_oid_fromstr(&id, loose_objects[i])); + cl_git_pass(git_oid__fromstr(&id, loose_objects[i], GIT_OID_SHA1)); cl_assert(git_odb_exists(_odb, &id) == 1); diff --git a/tests/libgit2/odb/packed256.c b/tests/libgit2/odb/packed256.c new file mode 100644 index 000000000..65220fd4c --- /dev/null +++ b/tests/libgit2/odb/packed256.c @@ -0,0 +1,98 @@ +#include "clar_libgit2.h" +#include "odb.h" +#include "pack_data_256.h" + +#ifdef GIT_EXPERIMENTAL_SHA256 +static git_odb *_odb; +#endif + +void test_odb_packed256__initialize(void) +{ +#ifdef GIT_EXPERIMENTAL_SHA256 + git_odb_options opts = GIT_ODB_OPTIONS_INIT; + + opts.oid_type = GIT_OID_SHA256; + + cl_git_pass(git_odb__open( + &_odb, + cl_fixture("testrepo_256.git/objects"), + &opts)); +#endif +} + +void test_odb_packed256__cleanup(void) +{ +#ifdef GIT_EXPERIMENTAL_SHA256 + git_odb_free(_odb); + _odb = NULL; +#endif +} + +void test_odb_packed256__mass_read(void) +{ +#ifdef GIT_EXPERIMENTAL_SHA256 + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(packed_objects_256); ++i) { + git_oid id; + git_odb_object *obj; + + cl_git_pass(git_oid__fromstr(&id, packed_objects_256[i], GIT_OID_SHA256)); + cl_assert(git_odb_exists(_odb, &id) == 1); + cl_git_pass(git_odb_read(&obj, _odb, &id)); + + git_odb_object_free(obj); + } +#endif +} + +void test_odb_packed256__read_header_0(void) +{ +#ifdef GIT_EXPERIMENTAL_SHA256 + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(packed_objects_256); ++i) { + git_oid id; + git_odb_object *obj; + size_t len; + git_object_t type; + + cl_git_pass(git_oid__fromstr(&id, packed_objects_256[i], GIT_OID_SHA256)); + + cl_git_pass(git_odb_read(&obj, _odb, &id)); + cl_git_pass(git_odb_read_header(&len, &type, _odb, &id)); + + cl_assert(obj->cached.size == len); + cl_assert(obj->cached.type == type); + + git_odb_object_free(obj); + } +#endif +} + +void test_odb_packed256__read_header_1(void) +{ +#ifdef GIT_EXPERIMENTAL_SHA256 + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(loose_objects_256); ++i) { + git_oid id; + git_odb_object *obj; + size_t len; + git_object_t type; + + cl_git_pass(git_oid__fromstr(&id, loose_objects_256[i], GIT_OID_SHA256)); + + cl_assert(git_odb_exists(_odb, &id) == 1); + + cl_git_pass(git_odb_read(&obj, _odb, &id)); + cl_git_pass(git_odb_read_header(&len, &type, _odb, &id)); + + cl_assert(obj->cached.size == len); + cl_assert(obj->cached.type == type); + + git_odb_object_free(obj); + } +#endif +} + diff --git a/tests/libgit2/odb/packed_one.c b/tests/libgit2/odb/packedone.c similarity index 55% rename from tests/libgit2/odb/packed_one.c rename to tests/libgit2/odb/packedone.c index 17cd4f760..8637001ff 100644 --- a/tests/libgit2/odb/packed_one.c +++ b/tests/libgit2/odb/packedone.c @@ -6,22 +6,29 @@ static git_odb *_odb; -void test_odb_packed_one__initialize(void) +void test_odb_packedone__initialize(void) { git_odb_backend *backend = NULL; - cl_git_pass(git_odb_new(&_odb)); - cl_git_pass(git_odb_backend_one_pack(&backend, cl_fixture("testrepo.git/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx"))); + cl_git_pass(git_odb__new(&_odb, NULL)); +#ifdef GIT_EXPERIMENTAL_SHA256 + cl_git_pass(git_odb_backend_one_pack(&backend, + cl_fixture("testrepo.git/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx"), + NULL)); +#else + cl_git_pass(git_odb_backend_one_pack(&backend, + cl_fixture("testrepo.git/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx"))); +#endif cl_git_pass(git_odb_add_backend(_odb, backend, 1)); } -void test_odb_packed_one__cleanup(void) +void test_odb_packedone__cleanup(void) { git_odb_free(_odb); _odb = NULL; } -void test_odb_packed_one__mass_read(void) +void test_odb_packedone__mass_read(void) { unsigned int i; @@ -29,7 +36,7 @@ void test_odb_packed_one__mass_read(void) git_oid id; git_odb_object *obj; - cl_git_pass(git_oid_fromstr(&id, packed_objects_one[i])); + cl_git_pass(git_oid__fromstr(&id, packed_objects_one[i], GIT_OID_SHA1)); cl_assert(git_odb_exists(_odb, &id) == 1); cl_git_pass(git_odb_read(&obj, _odb, &id)); @@ -37,7 +44,7 @@ void test_odb_packed_one__mass_read(void) } } -void test_odb_packed_one__read_header_0(void) +void test_odb_packedone__read_header_0(void) { unsigned int i; @@ -47,7 +54,7 @@ void test_odb_packed_one__read_header_0(void) size_t len; git_object_t type; - cl_git_pass(git_oid_fromstr(&id, packed_objects_one[i])); + cl_git_pass(git_oid__fromstr(&id, packed_objects_one[i], GIT_OID_SHA1)); cl_git_pass(git_odb_read(&obj, _odb, &id)); cl_git_pass(git_odb_read_header(&len, &type, _odb, &id)); diff --git a/tests/libgit2/odb/packedone256.c b/tests/libgit2/odb/packedone256.c new file mode 100644 index 000000000..fdeac4205 --- /dev/null +++ b/tests/libgit2/odb/packedone256.c @@ -0,0 +1,78 @@ +#include "clar_libgit2.h" +#include "git2/odb_backend.h" + +#include "pack_data_one256.h" +#include "pack.h" + +#ifdef GIT_EXPERIMENTAL_SHA256 +static git_odb *_odb; +#endif + +void test_odb_packedone256__initialize(void) +{ +#ifdef GIT_EXPERIMENTAL_SHA256 + git_odb_backend *backend = NULL; + git_odb_options odb_opts = GIT_ODB_OPTIONS_INIT; + git_odb_backend_pack_options backend_opts = GIT_ODB_BACKEND_PACK_OPTIONS_INIT; + + odb_opts.oid_type = GIT_OID_SHA256; + backend_opts.oid_type = GIT_OID_SHA256; + + cl_git_pass(git_odb__new(&_odb, &odb_opts)); + cl_git_pass(git_odb_backend_one_pack( + &backend, + cl_fixture("testrepo_256.git/objects/pack/pack-e2f07f30db7e480ea84a0e64ee791b9b270067124b2609019b74f33f256f33fa.idx"), + &backend_opts)); + cl_git_pass(git_odb_add_backend(_odb, backend, 1)); +#endif +} + +void test_odb_packedone256__cleanup(void) +{ +#ifdef GIT_EXPERIMENTAL_SHA256 + git_odb_free(_odb); + _odb = NULL; +#endif +} + +void test_odb_packedone256__mass_read(void) +{ +#ifdef GIT_EXPERIMENTAL_SHA256 + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(packed_objects_one256); ++i) { + git_oid id; + git_odb_object *obj; + + cl_git_pass(git_oid__fromstr(&id, packed_objects_one256[i], GIT_OID_SHA256)); + cl_assert(git_odb_exists(_odb, &id) == 1); + cl_git_pass(git_odb_read(&obj, _odb, &id)); + + git_odb_object_free(obj); + } +#endif +} + +void test_odb_packedone256__read_header_0(void) +{ +#ifdef GIT_EXPERIMENTAL_SHA256 + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(packed_objects_one256); ++i) { + git_oid id; + git_odb_object *obj; + size_t len; + git_object_t type; + + cl_git_pass(git_oid__fromstr(&id, packed_objects_one256[i], GIT_OID_SHA256)); + + cl_git_pass(git_odb_read(&obj, _odb, &id)); + cl_git_pass(git_odb_read_header(&len, &type, _odb, &id)); + + cl_assert(obj->cached.size == len); + cl_assert(obj->cached.type == type); + + git_odb_object_free(obj); + } +#endif +} diff --git a/tests/libgit2/odb/sorting.c b/tests/libgit2/odb/sorting.c index e027230fa..ec4e3696b 100644 --- a/tests/libgit2/odb/sorting.c +++ b/tests/libgit2/odb/sorting.c @@ -37,7 +37,7 @@ static git_odb *_odb; void test_odb_sorting__initialize(void) { - cl_git_pass(git_odb_new(&_odb)); + cl_git_pass(git_odb__new(&_odb, NULL)); } void test_odb_sorting__cleanup(void) @@ -79,12 +79,17 @@ void test_odb_sorting__override_default_backend_priority(void) { git_odb *new_odb; git_odb_backend *loose, *packed, *backend; + cl_git_pass(git_libgit2_opts(GIT_OPT_SET_ODB_LOOSE_PRIORITY, 5)); cl_git_pass(git_libgit2_opts(GIT_OPT_SET_ODB_PACKED_PRIORITY, 3)); - git_odb_backend_pack(&packed, "./testrepo.git/objects"); - git_odb_backend_loose(&loose, "./testrepo.git/objects", -1, 0, 0, 0); + git_odb_backend_pack(&packed, "./testrepo.git/objects" +#ifdef GIT_EXPERIMENTAL_SHA256 + , NULL +#endif + ); + git_odb__backend_loose(&loose, "./testrepo.git/objects", NULL); - cl_git_pass(git_odb_open(&new_odb, cl_fixture("testrepo.git/objects"))); + cl_git_pass(git_odb__open(&new_odb, cl_fixture("testrepo.git/objects"), NULL)); cl_assert_equal_sz(2, git_odb_num_backends(new_odb)); cl_git_pass(git_odb_get_backend(&backend, new_odb, 0)); diff --git a/tests/libgit2/online/clone.c b/tests/libgit2/online/clone.c index dfaee0e85..1a4cdb520 100644 --- a/tests/libgit2/online/clone.c +++ b/tests/libgit2/online/clone.c @@ -21,6 +21,7 @@ static git_clone_options g_options; static char *_remote_url = NULL; static char *_remote_user = NULL; static char *_remote_pass = NULL; +static char *_remote_branch = NULL; static char *_remote_sslnoverify = NULL; static char *_remote_ssh_pubkey = NULL; static char *_remote_ssh_privkey = NULL; @@ -35,6 +36,11 @@ static char *_remote_expectcontinue = NULL; static char *_remote_redirect_initial = NULL; static char *_remote_redirect_subsequent = NULL; +static char *_github_ssh_pubkey = NULL; +static char *_github_ssh_privkey = NULL; +static char *_github_ssh_passphrase = NULL; +static char *_github_ssh_remotehostkey = NULL; + static int _orig_proxies_need_reset = 0; static char *_orig_http_proxy = NULL; static char *_orig_https_proxy = NULL; @@ -69,6 +75,7 @@ void test_online_clone__initialize(void) _remote_url = cl_getenv("GITTEST_REMOTE_URL"); _remote_user = cl_getenv("GITTEST_REMOTE_USER"); _remote_pass = cl_getenv("GITTEST_REMOTE_PASS"); + _remote_branch = cl_getenv("GITTEST_REMOTE_BRANCH"); _remote_sslnoverify = cl_getenv("GITTEST_REMOTE_SSL_NOVERIFY"); _remote_ssh_pubkey = cl_getenv("GITTEST_REMOTE_SSH_PUBKEY"); _remote_ssh_privkey = cl_getenv("GITTEST_REMOTE_SSH_KEY"); @@ -83,6 +90,11 @@ void test_online_clone__initialize(void) _remote_redirect_initial = cl_getenv("GITTEST_REMOTE_REDIRECT_INITIAL"); _remote_redirect_subsequent = cl_getenv("GITTEST_REMOTE_REDIRECT_SUBSEQUENT"); + _github_ssh_pubkey = cl_getenv("GITTEST_GITHUB_SSH_PUBKEY"); + _github_ssh_privkey = cl_getenv("GITTEST_GITHUB_SSH_KEY"); + _github_ssh_passphrase = cl_getenv("GITTEST_GITHUB_SSH_PASSPHRASE"); + _github_ssh_remotehostkey = cl_getenv("GITTEST_GITHUB_SSH_REMOTE_HOSTKEY"); + if (_remote_expectcontinue) git_libgit2_opts(GIT_OPT_ENABLE_HTTP_EXPECT_CONTINUE, 1); @@ -102,6 +114,7 @@ void test_online_clone__cleanup(void) git__free(_remote_url); git__free(_remote_user); git__free(_remote_pass); + git__free(_remote_branch); git__free(_remote_sslnoverify); git__free(_remote_ssh_pubkey); git__free(_remote_ssh_privkey); @@ -116,6 +129,11 @@ void test_online_clone__cleanup(void) git__free(_remote_redirect_initial); git__free(_remote_redirect_subsequent); + git__free(_github_ssh_pubkey); + git__free(_github_ssh_privkey); + git__free(_github_ssh_passphrase); + git__free(_github_ssh_remotehostkey); + if (_orig_proxies_need_reset) { cl_setenv("HTTP_PROXY", _orig_http_proxy); cl_setenv("HTTPS_PROXY", _orig_https_proxy); @@ -309,6 +327,16 @@ void test_online_clone__custom_headers(void) cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options)); } +void test_online_clone__long_custom_header(void) +{ + /* Long custom header with 1500 characters */ + char *ok = "X-Custom: a0MsqH2bXV9lILn7zkAHqKpGrOVvkik7SfoyqfXbFTxccsymN5SG9hEB0RLD9koTXKWtaI1vI9jHf5ViwLHq6xvkveFX9GiqaIhe3TRu5KDZrOBgeufdBYsTTONALPlpni9XVq71bR6x3AlVEqHdXi9qiq0TRuNiujMy0ZKs8LQkQVSE8kxWZXqLsO2IJtAPw5aqsUEenK5ec12GOeOTOYlSChGllzvl2Ow4SKlVg3t8NHVWvc8HyPGmBQ79l3qUMU30P0hnUXaIrhIzGgleYWnwhGFLpryxsQfCdwkdBMuvtLH0DnkhLoAkCmnCZItEExtHBOCirEzztoFMX3lH4lM4wMqePCU8II0qloNvzPgt6cBThQJP66FYUDSCwsSb63bcTWdVx7TCa6mAplkP49PKi5pFSvFKKbs5se5MPcBVG03GiatKszIQkii0vp6OV5b54Aym4N8hQJHFMhIChKiQM91tB7PQu9vPJE6h2bzAnQsn34bBPFZHT7pBplqkASiHDjw69YV6k3M8ffTOTr2ibQnTKxh1NH3ZRx6u0KxRty9i4YLMniZUZAfFgqbSW2xXk49e8J9VNFm7j2bgHp3t813wUzqnQL4NEc0CQlF0e6pId5ADXikoH6S7aMfuYUYi1Kn1i9m7UGtaB0U7dVC65uH9vIWKnyAcmBt0mN1aikRnjz7oBKjD65SRZrKWXeCDJkpgWlXnD5JjekDCyB9m3yGkaxy1FflI1kaa4kcVbPRfs6XebHRDl9golPBUyazRG1V1iOi1mKki9ClUNO8wviNfKm5eMbWW6hU8wMXh388EotRA73TUdL4JIfNpkC4XBFLNFbFtltzO34kxXBKvhj8t0XVZOp4AWpHEL3pUtuyKhNWaWlDF6ZhjCeO8vT1akKoYaA7t6nFyqawq5nPoB0iXEHQ7YugfYfgjzpNGLgvPJ6aLg9YIKZBqfi7J9xWb356IJvTQFswi7qm6Mu7IVXarS9m84b5IfT6UCVq84u4VcdBlDswNPTw6SbBtzg9vrLLs3MoTCzJY6fHPqnKt6YthgQwOOB1ig7GTSDiX3W3SMeaz5jTASociHrUS3HrwVSgjrODnF86962cv4s3DGYjiX2cIuNfq9mZVJlNsylZjFYFV9LzOjNLlSHZVJrrGQJLjmyOCwOMkG9u2xKdSvfjxTJzqhjhTvQSQZWhKt44hA9EidUqPqjc3MhfnZ6aeAIP232gtRHoRc7FdjRSan4Q3PWy02YiRodvKAafonwCOtMcm4MASrXBiBE1tibHLSTtK4UrodFNVhymtBCRnJdVRSgrCQcr2B5Jzs4Iv6uJlJqwwyuq6In54zcmecgJZezta84B3eFoSGJhCbI6Zza0khulccglCcppciWDStAHFhncePsCQL4tup0Z8fS01RksRQ7X1xgskVvQAKELThDqbJB4FJZwrwPXOpCweAoSONntp7Ly0lAUabw75gK5sR387IxNVdISmfP"; + + g_options.fetch_opts.custom_headers.count = 1; + g_options.fetch_opts.custom_headers.strings = &ok; + cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options)); +} + static int cred_failure_cb( git_credential **cred, const char *url, @@ -484,9 +512,13 @@ void test_online_clone__bitbucket_falls_back_to_specified_creds(void) void test_online_clone__googlesource(void) { +#ifdef __APPLE__ + cl_skip(); +#else cl_git_pass(git_clone(&g_repo, GOOGLESOURCE_REPO_URL, "./foo", &g_options)); git_repository_free(g_repo); g_repo = NULL; cl_fixture_cleanup("./foo"); +#endif } static int cancel_at_half(const git_indexer_progress *stats, void *payload) @@ -537,6 +569,68 @@ static int check_ssh_auth_methods(git_credential **cred, const char *url, const return GIT_EUSER; } +static int succeed_certificate_check(git_cert *cert, int valid, const char *host, void *payload) +{ + GIT_UNUSED(cert); + GIT_UNUSED(valid); + GIT_UNUSED(payload); + + cl_assert_equal_s("github.com", host); + + return 0; +} + +static int fail_certificate_check(git_cert *cert, int valid, const char *host, void *payload) +{ + GIT_UNUSED(cert); + GIT_UNUSED(valid); + GIT_UNUSED(host); + GIT_UNUSED(payload); + + return GIT_ECERTIFICATE; +} + +static int github_credentials( + git_credential **cred, + const char *url, + const char *username_from_url, + unsigned int allowed_types, + void *data) +{ + GIT_UNUSED(url); + GIT_UNUSED(username_from_url); + GIT_UNUSED(data); + + if ((allowed_types & GIT_CREDENTIAL_USERNAME) != 0) { + return git_credential_username_new(cred, "git"); + } + + cl_assert((allowed_types & GIT_CREDENTIAL_SSH_KEY) != 0); + + return git_credential_ssh_key_memory_new(cred, + "git", + _github_ssh_pubkey, + _github_ssh_privkey, + _github_ssh_passphrase); +} + +void test_online_clone__ssh_github(void) +{ +#if !defined(GIT_SSH) || !defined(GIT_SSH_MEMORY_CREDENTIALS) + clar__skip(); +#endif + + if (!_github_ssh_pubkey || !_github_ssh_privkey) + clar__skip(); + + cl_fake_homedir(NULL); + + g_options.fetch_opts.callbacks.credentials = github_credentials; + g_options.fetch_opts.callbacks.certificate_check = succeed_certificate_check; + + cl_git_pass(git_clone(&g_repo, SSH_REPO_URL, "./foo", &g_options)); +} + void test_online_clone__ssh_auth_methods(void) { int with_user; @@ -546,7 +640,7 @@ void test_online_clone__ssh_auth_methods(void) #endif g_options.fetch_opts.callbacks.credentials = check_ssh_auth_methods; g_options.fetch_opts.callbacks.payload = &with_user; - g_options.fetch_opts.callbacks.certificate_check = NULL; + g_options.fetch_opts.callbacks.certificate_check = succeed_certificate_check; with_user = 0; cl_git_fail_with(GIT_EUSER, @@ -557,6 +651,69 @@ void test_online_clone__ssh_auth_methods(void) git_clone(&g_repo, "ssh://git@github.com/libgit2/TestGitRepository", "./foo", &g_options)); } +/* + * Ensure that the certificate check callback is still called, and + * can accept a host key that is not in the known hosts file. + */ +void test_online_clone__ssh_certcheck_accepts_unknown(void) +{ +#if !defined(GIT_SSH) || !defined(GIT_SSH_MEMORY_CREDENTIALS) + clar__skip(); +#endif + + if (!_github_ssh_pubkey || !_github_ssh_privkey) + clar__skip(); + + cl_fake_homedir(NULL); + + g_options.fetch_opts.callbacks.credentials = github_credentials; + + /* Ensure we fail without the certificate check */ + cl_git_fail_with(GIT_ECERTIFICATE, + git_clone(&g_repo, SSH_REPO_URL, "./foo", NULL)); + + /* Set the callback to accept the certificate */ + g_options.fetch_opts.callbacks.certificate_check = succeed_certificate_check; + + cl_git_pass(git_clone(&g_repo, SSH_REPO_URL, "./foo", &g_options)); +} + +/* + * Ensure that the known hosts file is read and the certificate check + * callback is still called after that. + */ +void test_online_clone__ssh_certcheck_override_knownhosts(void) +{ + git_str knownhostsfile = GIT_STR_INIT; + +#if !defined(GIT_SSH) || !defined(GIT_SSH_MEMORY_CREDENTIALS) + clar__skip(); +#endif + + if (!_github_ssh_pubkey || !_github_ssh_privkey || !_github_ssh_remotehostkey) + clar__skip(); + + g_options.fetch_opts.callbacks.credentials = github_credentials; + + cl_fake_homedir(&knownhostsfile); + cl_git_pass(git_str_joinpath(&knownhostsfile, knownhostsfile.ptr, ".ssh")); + cl_git_pass(p_mkdir(knownhostsfile.ptr, 0777)); + + cl_git_pass(git_str_joinpath(&knownhostsfile, knownhostsfile.ptr, "known_hosts")); + cl_git_rewritefile(knownhostsfile.ptr, _github_ssh_remotehostkey); + + /* Ensure we succeed without the certificate check */ + cl_git_pass(git_clone(&g_repo, SSH_REPO_URL, "./foo", &g_options)); + git_repository_free(g_repo); + g_repo = NULL; + + /* Set the callback to reject the certificate */ + g_options.fetch_opts.callbacks.certificate_check = fail_certificate_check; + cl_git_fail_with(GIT_ECERTIFICATE, git_clone(&g_repo, SSH_REPO_URL, "./bar", &g_options)); + + git_str_dispose(&knownhostsfile); +} + static int custom_remote_ssh_with_paths( git_remote **out, git_repository *repo, @@ -629,14 +786,14 @@ void test_online_clone__ssh_cannot_change_username(void) static int ssh_certificate_check(git_cert *cert, int valid, const char *host, void *payload) { git_cert_hostkey *key; - git_oid expected = {{0}}, actual = {{0}}; + git_oid expected = GIT_OID_SHA1_ZERO, actual = GIT_OID_SHA1_ZERO; GIT_UNUSED(valid); GIT_UNUSED(payload); cl_assert(_remote_ssh_fingerprint); - cl_git_pass(git_oid_fromstrp(&expected, _remote_ssh_fingerprint)); + cl_git_pass(git_oid__fromstrp(&expected, _remote_ssh_fingerprint, GIT_OID_SHA1)); cl_assert_equal_i(GIT_CERT_HOSTKEY_LIBSSH2, cert->cert_type); key = (git_cert_hostkey *) cert; @@ -729,16 +886,6 @@ void test_online_clone__ssh_memory_auth(void) cl_git_pass(git_clone(&g_repo, _remote_url, "./foo", &g_options)); } -static int fail_certificate_check(git_cert *cert, int valid, const char *host, void *payload) -{ - GIT_UNUSED(cert); - GIT_UNUSED(valid); - GIT_UNUSED(host); - GIT_UNUSED(payload); - - return GIT_ECERTIFICATE; -} - void test_online_clone__certificate_invalid(void) { g_options.fetch_opts.callbacks.certificate_check = fail_certificate_check; @@ -752,17 +899,6 @@ void test_online_clone__certificate_invalid(void) #endif } -static int succeed_certificate_check(git_cert *cert, int valid, const char *host, void *payload) -{ - GIT_UNUSED(cert); - GIT_UNUSED(valid); - GIT_UNUSED(payload); - - cl_assert_equal_s("github.com", host); - - return 0; -} - void test_online_clone__certificate_valid(void) { g_options.fetch_opts.callbacks.certificate_check = succeed_certificate_check; @@ -1002,3 +1138,61 @@ void test_online_clone__redirect_initial_fails_for_subsequent(void) cl_git_fail(git_clone(&g_repo, _remote_redirect_subsequent, "./fail", &options)); } + +void test_online_clone__namespace_bare(void) +{ + git_clone_options options = GIT_CLONE_OPTIONS_INIT; + git_reference *head; + + if (!_remote_url) + cl_skip(); + + options.bare = true; + + cl_git_pass(git_clone(&g_repo, _remote_url, "./namespaced.git", &options)); + + cl_git_pass(git_reference_lookup(&head, g_repo, GIT_HEAD_FILE)); + cl_assert_equal_i(GIT_REFERENCE_SYMBOLIC, git_reference_type(head)); + cl_assert_equal_s("refs/heads/master", git_reference_symbolic_target(head)); + + git_reference_free(head); +} + +void test_online_clone__namespace_with_specified_branch(void) +{ + git_clone_options options = GIT_CLONE_OPTIONS_INIT; + git_reference *head; + + if (!_remote_url || !_remote_branch) + cl_skip(); + + options.checkout_branch = _remote_branch; + + cl_git_pass(git_clone(&g_repo, _remote_url, "./namespaced", &options)); + + cl_git_pass(git_reference_lookup(&head, g_repo, GIT_HEAD_FILE)); + cl_assert_equal_i(GIT_REFERENCE_SYMBOLIC, git_reference_type(head)); + cl_assert_equal_strn("refs/heads/", git_reference_symbolic_target(head), 11); + cl_assert_equal_s(_remote_branch, git_reference_symbolic_target(head) + 11); + + git_reference_free(head); +} + +void test_online_clone__sha256(void) +{ +#ifndef GIT_EXPERIMENTAL_SHA256 + cl_skip(); +#else + git_clone_options options = GIT_CLONE_OPTIONS_INIT; + git_reference *head; + + if (!_remote_url) + cl_skip(); + + cl_git_pass(git_clone(&g_repo, _remote_url, "./sha256", &options)); + cl_git_pass(git_reference_lookup(&head, g_repo, GIT_HEAD_FILE)); + cl_assert_equal_i(GIT_REFERENCE_SYMBOLIC, git_reference_type(head)); + + git_reference_free(head); +#endif +} diff --git a/tests/libgit2/online/fetch.c b/tests/libgit2/online/fetch.c index 5beb5b618..a557bbf75 100644 --- a/tests/libgit2/online/fetch.c +++ b/tests/libgit2/online/fetch.c @@ -304,7 +304,7 @@ void test_online_fetch__reachable_commit(void) refspecs.strings = &refspec; refspecs.count = 1; - git_oid_fromstr(&expected_id, "2c349335b7f797072cf729c4f3bb0914ecb6dec9"); + git_oid__fromstr(&expected_id, "2c349335b7f797072cf729c4f3bb0914ecb6dec9", GIT_OID_SHA1); cl_git_pass(git_remote_create(&remote, _repo, "test", "https://github.com/libgit2/TestGitRepository")); @@ -334,7 +334,7 @@ void test_online_fetch__reachable_commit_without_destination(void) refspecs.strings = &refspec; refspecs.count = 1; - git_oid_fromstr(&expected_id, "2c349335b7f797072cf729c4f3bb0914ecb6dec9"); + git_oid__fromstr(&expected_id, "2c349335b7f797072cf729c4f3bb0914ecb6dec9", GIT_OID_SHA1); cl_git_pass(git_remote_create(&remote, _repo, "test", "https://github.com/libgit2/TestGitRepository")); diff --git a/tests/libgit2/online/push.c b/tests/libgit2/online/push.c index 51adc3930..204572cf5 100644 --- a/tests/libgit2/online/push.c +++ b/tests/libgit2/online/push.c @@ -344,18 +344,18 @@ void test_online_push__initialize(void) * * a78705c3b2725f931d3ee05348d83cc26700f247 (b2, b1) added fold and fold/b.txt * * 5c0bb3d1b9449d1cc69d7519fd05166f01840915 added a.txt */ - git_oid_fromstr(&_oid_b6, "951bbbb90e2259a4c8950db78946784fb53fcbce"); - git_oid_fromstr(&_oid_b5, "fa38b91f199934685819bea316186d8b008c52a2"); - git_oid_fromstr(&_oid_b4, "27b7ce66243eb1403862d05f958c002312df173d"); - git_oid_fromstr(&_oid_b3, "d9b63a88223d8367516f50bd131a5f7349b7f3e4"); - git_oid_fromstr(&_oid_b2, "a78705c3b2725f931d3ee05348d83cc26700f247"); - git_oid_fromstr(&_oid_b1, "a78705c3b2725f931d3ee05348d83cc26700f247"); + git_oid__fromstr(&_oid_b6, "951bbbb90e2259a4c8950db78946784fb53fcbce", GIT_OID_SHA1); + git_oid__fromstr(&_oid_b5, "fa38b91f199934685819bea316186d8b008c52a2", GIT_OID_SHA1); + git_oid__fromstr(&_oid_b4, "27b7ce66243eb1403862d05f958c002312df173d", GIT_OID_SHA1); + git_oid__fromstr(&_oid_b3, "d9b63a88223d8367516f50bd131a5f7349b7f3e4", GIT_OID_SHA1); + git_oid__fromstr(&_oid_b2, "a78705c3b2725f931d3ee05348d83cc26700f247", GIT_OID_SHA1); + git_oid__fromstr(&_oid_b1, "a78705c3b2725f931d3ee05348d83cc26700f247", GIT_OID_SHA1); - git_oid_fromstr(&_tag_commit, "805c54522e614f29f70d2413a0470247d8b424ac"); - git_oid_fromstr(&_tag_tree, "ff83aa4c5e5d28e3bcba2f5c6e2adc61286a4e5e"); - git_oid_fromstr(&_tag_blob, "b483ae7ba66decee9aee971f501221dea84b1498"); - git_oid_fromstr(&_tag_lightweight, "951bbbb90e2259a4c8950db78946784fb53fcbce"); - git_oid_fromstr(&_tag_tag, "eea4f2705eeec2db3813f2430829afce99cd00b5"); + git_oid__fromstr(&_tag_commit, "805c54522e614f29f70d2413a0470247d8b424ac", GIT_OID_SHA1); + git_oid__fromstr(&_tag_tree, "ff83aa4c5e5d28e3bcba2f5c6e2adc61286a4e5e", GIT_OID_SHA1); + git_oid__fromstr(&_tag_blob, "b483ae7ba66decee9aee971f501221dea84b1498", GIT_OID_SHA1); + git_oid__fromstr(&_tag_lightweight, "951bbbb90e2259a4c8950db78946784fb53fcbce", GIT_OID_SHA1); + git_oid__fromstr(&_tag_tag, "eea4f2705eeec2db3813f2430829afce99cd00b5", GIT_OID_SHA1); /* Remote URL environment variable must be set. User and password are optional. */ @@ -841,13 +841,28 @@ void test_online_push__bad_refspecs(void) void test_online_push__expressions(void) { - /* TODO: Expressions in refspecs doesn't actually work yet */ - const char *specs_left_expr[] = { "refs/heads/b2~1:refs/heads/b2" }; + const char *specs_left_expr[] = { + "refs/heads/b3~1:refs/heads/b2", + "b4:refs/heads/b4", + "fa38b91f199934685819bea316186d8b008c52a2:refs/heads/b5", + "951bbbb:refs/heads/b6" + }; + push_status exp_stats[] = { + { "refs/heads/b2", 1 }, + { "refs/heads/b4", 1 }, + { "refs/heads/b5", 1 }, + { "refs/heads/b6", 1 } + }; + expected_ref exp_refs[] = { + { "refs/heads/b2", &_oid_b2 }, + { "refs/heads/b4", &_oid_b4 }, + { "refs/heads/b5", &_oid_b5 }, + { "refs/heads/b6", &_oid_b6 } + }; - /* TODO: Find a more precise way of checking errors than a exit code of -1. */ do_push(specs_left_expr, ARRAY_SIZE(specs_left_expr), - NULL, 0, - NULL, 0, -1, 0, 0); + exp_stats, ARRAY_SIZE(exp_stats), + exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); } void test_online_push__notes(void) @@ -859,7 +874,7 @@ void test_online_push__notes(void) expected_ref exp_refs[] = { { "refs/notes/commits", &expected_oid } }; const char *specs_del[] = { ":refs/notes/commits" }; - git_oid_fromstr(&expected_oid, "8461a99b27b7043e58ff6e1f5d2cf07d282534fb"); + git_oid__fromstr(&expected_oid, "8461a99b27b7043e58ff6e1f5d2cf07d282534fb", GIT_OID_SHA1); target_oid = &_oid_b6; @@ -890,7 +905,7 @@ void test_online_push__configured(void) expected_ref exp_refs[] = { { "refs/notes/commits", &expected_oid } }; const char *specs_del[] = { ":refs/notes/commits" }; - git_oid_fromstr(&expected_oid, "8461a99b27b7043e58ff6e1f5d2cf07d282534fb"); + git_oid__fromstr(&expected_oid, "8461a99b27b7043e58ff6e1f5d2cf07d282534fb", GIT_OID_SHA1); target_oid = &_oid_b6; diff --git a/tests/libgit2/online/push_util.c b/tests/libgit2/online/push_util.c index cd1831d4c..94919e9b2 100644 --- a/tests/libgit2/online/push_util.c +++ b/tests/libgit2/online/push_util.c @@ -2,8 +2,6 @@ #include "vector.h" #include "push_util.h" -const git_oid OID_ZERO = {{ 0 }}; - void updated_tip_free(updated_tip *t) { git__free(t->name); diff --git a/tests/libgit2/pack/indexer.c b/tests/libgit2/pack/indexer.c index 94b2cc92e..9722decaf 100644 --- a/tests/libgit2/pack/indexer.c +++ b/tests/libgit2/pack/indexer.c @@ -100,7 +100,12 @@ void test_pack_indexer__out_of_order(void) git_indexer *idx = 0; git_indexer_progress stats = { 0 }; +#ifdef GIT_EXPERIMENTAL_SHA256 + cl_git_pass(git_indexer_new(&idx, ".", GIT_OID_SHA1, NULL)); +#else cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL)); +#endif + cl_git_pass(git_indexer_append( idx, out_of_order_pack, out_of_order_pack_len, &stats)); cl_git_pass(git_indexer_commit(idx, &stats)); @@ -117,7 +122,12 @@ void test_pack_indexer__missing_trailer(void) git_indexer *idx = 0; git_indexer_progress stats = { 0 }; +#ifdef GIT_EXPERIMENTAL_SHA256 + cl_git_pass(git_indexer_new(&idx, ".", GIT_OID_SHA1, NULL)); +#else cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL)); +#endif + cl_git_pass(git_indexer_append( idx, missing_trailer_pack, missing_trailer_pack_len, &stats)); cl_git_fail(git_indexer_commit(idx, &stats)); @@ -133,7 +143,12 @@ void test_pack_indexer__leaky(void) git_indexer *idx = 0; git_indexer_progress stats = { 0 }; +#ifdef GIT_EXPERIMENTAL_SHA256 + cl_git_pass(git_indexer_new(&idx, ".", GIT_OID_SHA1, NULL)); +#else cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL)); +#endif + cl_git_pass(git_indexer_append( idx, leaky_pack, leaky_pack_len, &stats)); cl_git_fail(git_indexer_commit(idx, &stats)); @@ -151,16 +166,23 @@ void test_pack_indexer__fix_thin(void) git_repository *repo; git_odb *odb; git_oid id, should_id; + git_indexer_options opts = GIT_INDEXER_OPTIONS_INIT; cl_git_pass(git_repository_init(&repo, "thin.git", true)); cl_git_pass(git_repository_odb(&odb, repo)); /* Store the missing base into your ODB so the indexer can fix the pack */ cl_git_pass(git_odb_write(&id, odb, base_obj, base_obj_len, GIT_OBJECT_BLOB)); - git_oid_fromstr(&should_id, "e68fe8129b546b101aee9510c5328e7f21ca1d18"); + git_oid__fromstr(&should_id, "e68fe8129b546b101aee9510c5328e7f21ca1d18", GIT_OID_SHA1); cl_assert_equal_oid(&should_id, &id); - cl_git_pass(git_indexer_new(&idx, ".", 0, odb, NULL)); +#ifdef GIT_EXPERIMENTAL_SHA256 + opts.odb = odb; + cl_git_pass(git_indexer_new(&idx, ".", GIT_OID_SHA1, &opts)); +#else + cl_git_pass(git_indexer_new(&idx, ".", 0, odb, &opts)); +#endif + cl_git_pass(git_indexer_append(idx, thin_pack, thin_pack_len, &stats)); cl_git_pass(git_indexer_commit(idx, &stats)); @@ -192,7 +214,12 @@ void test_pack_indexer__fix_thin(void) cl_git_pass(p_stat(name, &st)); +#ifdef GIT_EXPERIMENTAL_SHA256 + cl_git_pass(git_indexer_new(&idx, ".", GIT_OID_SHA1, NULL)); +#else cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL)); +#endif + read = p_read(fd, buffer, sizeof(buffer)); cl_assert(read != -1); p_close(fd); @@ -216,16 +243,23 @@ void test_pack_indexer__corrupt_length(void) git_repository *repo; git_odb *odb; git_oid id, should_id; + git_indexer_options opts = GIT_INDEXER_OPTIONS_INIT; cl_git_pass(git_repository_init(&repo, "thin.git", true)); cl_git_pass(git_repository_odb(&odb, repo)); /* Store the missing base into your ODB so the indexer can fix the pack */ cl_git_pass(git_odb_write(&id, odb, base_obj, base_obj_len, GIT_OBJECT_BLOB)); - git_oid_fromstr(&should_id, "e68fe8129b546b101aee9510c5328e7f21ca1d18"); + git_oid__fromstr(&should_id, "e68fe8129b546b101aee9510c5328e7f21ca1d18", GIT_OID_SHA1); cl_assert_equal_oid(&should_id, &id); - cl_git_pass(git_indexer_new(&idx, ".", 0, odb, NULL)); +#ifdef GIT_EXPERIMENTAL_SHA256 + opts.odb = odb; + cl_git_pass(git_indexer_new(&idx, ".", GIT_OID_SHA1, &opts)); +#else + cl_git_pass(git_indexer_new(&idx, ".", 0, odb, &opts)); +#endif + cl_git_pass(git_indexer_append( idx, corrupt_thin_pack, corrupt_thin_pack_len, &stats)); cl_git_fail(git_indexer_commit(idx, &stats)); @@ -246,7 +280,12 @@ void test_pack_indexer__incomplete_pack_fails_with_strict(void) opts.verify = 1; +#ifdef GIT_EXPERIMENTAL_SHA256 + cl_git_pass(git_indexer_new(&idx, ".", GIT_OID_SHA1, &opts)); +#else cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, &opts)); +#endif + cl_git_pass(git_indexer_append( idx, incomplete_pack, incomplete_pack_len, &stats)); cl_git_fail(git_indexer_commit(idx, &stats)); @@ -266,7 +305,12 @@ void test_pack_indexer__out_of_order_with_connectivity_checks(void) opts.verify = 1; +#ifdef GIT_EXPERIMENTAL_SHA256 + cl_git_pass(git_indexer_new(&idx, ".", GIT_OID_SHA1, &opts)); +#else cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, &opts)); +#endif + cl_git_pass(git_indexer_append( idx, out_of_order_pack, out_of_order_pack_len, &stats)); cl_git_pass(git_indexer_commit(idx, &stats)); @@ -309,7 +353,12 @@ void test_pack_indexer__no_tmp_files(void) git_str_dispose(&path); cl_assert(git_str_len(&first_tmp_file) == 0); +#ifdef GIT_EXPERIMENTAL_SHA256 + cl_git_pass(git_indexer_new(&idx, ".", GIT_OID_SHA1, NULL)); +#else cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL)); +#endif + git_indexer_free(idx); cl_git_pass(git_str_sets(&path, clar_sandbox_path())); diff --git a/tests/libgit2/pack/midx.c b/tests/libgit2/pack/midx.c index 9dd949363..f7d680165 100644 --- a/tests/libgit2/pack/midx.c +++ b/tests/libgit2/pack/midx.c @@ -19,8 +19,8 @@ void test_pack_midx__parse(void) cl_git_pass(git_midx_open(&idx, git_str_cstr(&midx_path))); cl_assert_equal_i(git_midx_needs_refresh(idx, git_str_cstr(&midx_path)), 0); - cl_git_pass(git_oid_fromstr(&id, "5001298e0c09ad9c34e4249bc5801c75e9754fa5")); - cl_git_pass(git_midx_entry_find(&e, idx, &id, GIT_OID_HEXSZ)); + cl_git_pass(git_oid__fromstr(&id, "5001298e0c09ad9c34e4249bc5801c75e9754fa5", GIT_OID_SHA1)); + cl_git_pass(git_midx_entry_find(&e, idx, &id, GIT_OID_SHA1_HEXSIZE)); cl_assert_equal_oid(&e.sha1, &id); cl_assert_equal_s( (const char *)git_vector_get(&idx->packfile_names, e.pack_index), @@ -39,8 +39,8 @@ void test_pack_midx__lookup(void) cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git"))); - cl_git_pass(git_oid_fromstr(&id, "5001298e0c09ad9c34e4249bc5801c75e9754fa5")); - cl_git_pass(git_commit_lookup_prefix(&commit, repo, &id, GIT_OID_HEXSZ)); + cl_git_pass(git_oid__fromstr(&id, "5001298e0c09ad9c34e4249bc5801c75e9754fa5", GIT_OID_SHA1)); + cl_git_pass(git_commit_lookup_prefix(&commit, repo, &id, GIT_OID_SHA1_HEXSIZE)); cl_assert_equal_s(git_commit_message(commit), "packed commit one\n"); git_commit_free(commit); diff --git a/tests/libgit2/pack/packbuilder.c b/tests/libgit2/pack/packbuilder.c index 0889f46ed..ff3dc1f68 100644 --- a/tests/libgit2/pack/packbuilder.c +++ b/tests/libgit2/pack/packbuilder.c @@ -104,7 +104,12 @@ void test_pack_packbuilder__create_pack(void) seed_packbuilder(); +#ifdef GIT_EXPERIMENTAL_SHA256 + cl_git_pass(git_indexer_new(&_indexer, ".", GIT_OID_SHA1, NULL)); +#else cl_git_pass(git_indexer_new(&_indexer, ".", 0, NULL, NULL)); +#endif + cl_git_pass(git_packbuilder_foreach(_packbuilder, feed_indexer, &stats)); cl_git_pass(git_indexer_commit(_indexer, &stats)); @@ -244,7 +249,13 @@ void test_pack_packbuilder__foreach(void) git_indexer *idx; seed_packbuilder(); + +#ifdef GIT_EXPERIMENTAL_SHA256 + cl_git_pass(git_indexer_new(&idx, ".", GIT_OID_SHA1, NULL)); +#else cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL)); +#endif + cl_git_pass(git_packbuilder_foreach(_packbuilder, foreach_cb, idx)); cl_git_pass(git_indexer_commit(idx, &_stats)); git_indexer_free(idx); @@ -262,7 +273,13 @@ void test_pack_packbuilder__foreach_with_cancel(void) git_indexer *idx; seed_packbuilder(); + +#ifdef GIT_EXPERIMENTAL_SHA256 + cl_git_pass(git_indexer_new(&idx, ".", GIT_OID_SHA1, NULL)); +#else cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL)); +#endif + cl_git_fail_with( git_packbuilder_foreach(_packbuilder, foreach_cancel_cb, idx), -1111); git_indexer_free(idx); diff --git a/tests/libgit2/pack/sharing.c b/tests/libgit2/pack/sharing.c index eaf7686b7..2e2042d2b 100644 --- a/tests/libgit2/pack/sharing.c +++ b/tests/libgit2/pack/sharing.c @@ -18,7 +18,7 @@ void test_pack_sharing__open_two_repos(void) cl_git_pass(git_repository_open(&repo1, cl_fixture("testrepo.git"))); cl_git_pass(git_repository_open(&repo2, cl_fixture("testrepo.git"))); - git_oid_fromstr(&id, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"); + git_oid__fromstr(&id, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", GIT_OID_SHA1); cl_git_pass(git_object_lookup(&obj1, repo1, &id, GIT_OBJECT_ANY)); cl_git_pass(git_object_lookup(&obj2, repo2, &id, GIT_OBJECT_ANY)); diff --git a/tests/libgit2/patch/parse.c b/tests/libgit2/patch/parse.c index a3c4c6730..d90576e46 100644 --- a/tests/libgit2/patch/parse.c +++ b/tests/libgit2/patch/parse.c @@ -7,7 +7,7 @@ static void ensure_patch_validity(git_patch *patch) { const git_diff_delta *delta; - char idstr[GIT_OID_HEXSZ+1] = {0}; + char idstr[GIT_OID_SHA1_HEXSIZE+1] = {0}; cl_assert((delta = git_patch_get_delta(patch)) != NULL); cl_assert_equal_i(2, delta->nfiles); diff --git a/tests/libgit2/perf/helper__perf__do_merge.c b/tests/libgit2/perf/helper__perf__do_merge.c index c77b46a1f..eb10524ec 100644 --- a/tests/libgit2/perf/helper__perf__do_merge.c +++ b/tests/libgit2/perf/helper__perf__do_merge.c @@ -33,7 +33,7 @@ void perf__do_merge(const char *fixture, cl_git_pass(git_clone(&g_repo, fixture, test_name, &clone_opts)); perf__timer__stop(&t_clone); - git_oid_fromstr(&oid_a, id_a); + git_oid__fromstr(&oid_a, id_a, GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit_a, g_repo, &oid_a)); cl_git_pass(git_branch_create(&ref_branch_a, g_repo, "A", commit_a, @@ -45,7 +45,7 @@ void perf__do_merge(const char *fixture, cl_git_pass(git_repository_set_head(g_repo, git_reference_name(ref_branch_a))); - git_oid_fromstr(&oid_b, id_b); + git_oid__fromstr(&oid_b, id_b, GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit_b, g_repo, &oid_b)); cl_git_pass(git_branch_create(&ref_branch_b, g_repo, "B", commit_b, diff --git a/tests/libgit2/rebase/abort.c b/tests/libgit2/rebase/abort.c index a83c529ce..da0dfe893 100644 --- a/tests/libgit2/rebase/abort.c +++ b/tests/libgit2/rebase/abort.c @@ -128,8 +128,8 @@ void test_rebase_abort__merge_by_id(void) git_oid branch_id, onto_id; git_annotated_commit *branch_head, *onto_head; - cl_git_pass(git_oid_fromstr(&branch_id, "b146bd7608eac53d9bf9e1a6963543588b555c64")); - cl_git_pass(git_oid_fromstr(&onto_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00")); + cl_git_pass(git_oid__fromstr(&branch_id, "b146bd7608eac53d9bf9e1a6963543588b555c64", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&onto_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00", GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&branch_head, repo, &branch_id)); cl_git_pass(git_annotated_commit_lookup(&onto_head, repo, &onto_id)); @@ -170,8 +170,8 @@ void test_rebase_abort__merge_by_id_immediately_after_init(void) git_oid branch_id, onto_id; git_annotated_commit *branch_head, *onto_head; - cl_git_pass(git_oid_fromstr(&branch_id, "b146bd7608eac53d9bf9e1a6963543588b555c64")); - cl_git_pass(git_oid_fromstr(&onto_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00")); + cl_git_pass(git_oid__fromstr(&branch_id, "b146bd7608eac53d9bf9e1a6963543588b555c64", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&onto_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00", GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&branch_head, repo, &branch_id)); cl_git_pass(git_annotated_commit_lookup(&onto_head, repo, &onto_id)); @@ -195,8 +195,8 @@ void test_rebase_abort__detached_head(void) git_signature *signature; git_annotated_commit *branch_head, *onto_head; - git_oid_fromstr(&branch_id, "b146bd7608eac53d9bf9e1a6963543588b555c64"); - git_oid_fromstr(&onto_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00"); + git_oid__fromstr(&branch_id, "b146bd7608eac53d9bf9e1a6963543588b555c64", GIT_OID_SHA1); + git_oid__fromstr(&onto_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00", GIT_OID_SHA1); cl_git_pass(git_annotated_commit_lookup(&branch_head, repo, &branch_id)); cl_git_pass(git_annotated_commit_lookup(&onto_head, repo, &onto_id)); diff --git a/tests/libgit2/rebase/inmemory.c b/tests/libgit2/rebase/inmemory.c index 040a81b1b..287dd9911 100644 --- a/tests/libgit2/rebase/inmemory.c +++ b/tests/libgit2/rebase/inmemory.c @@ -74,7 +74,7 @@ void test_rebase_inmemory__can_resolve_conflicts(void) cl_git_pass(git_rebase_next(&rebase_operation, rebase)); - git_oid_fromstr(&pick_id, "33f915f9e4dbd9f4b24430e48731a59b45b15500"); + git_oid__fromstr(&pick_id, "33f915f9e4dbd9f4b24430e48731a59b45b15500", GIT_OID_SHA1); cl_assert_equal_i(GIT_REBASE_OPERATION_PICK, rebase_operation->type); cl_assert_equal_oid(&pick_id, &rebase_operation->id); @@ -95,14 +95,14 @@ void test_rebase_inmemory__can_resolve_conflicts(void) /* ensure that we can work with the in-memory index to resolve the conflict */ resolution.path = "asparagus.txt"; resolution.mode = GIT_FILEMODE_BLOB; - git_oid_fromstr(&resolution.id, "414dfc71ead79c07acd4ea47fecf91f289afc4b9"); + git_oid__fromstr(&resolution.id, "414dfc71ead79c07acd4ea47fecf91f289afc4b9", GIT_OID_SHA1); cl_git_pass(git_index_conflict_remove(rebase_index, "asparagus.txt")); cl_git_pass(git_index_add(rebase_index, &resolution)); /* and finally create a commit for the resolved rebase operation */ cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature, NULL, NULL)); - cl_git_pass(git_oid_fromstr(&expected_commit_id, "db7af47222181e548810da2ab5fec0e9357c5637")); + cl_git_pass(git_oid__fromstr(&expected_commit_id, "db7af47222181e548810da2ab5fec0e9357c5637", GIT_OID_SHA1)); cl_assert_equal_oid(&commit_id, &expected_commit_id); git_status_list_free(status_list); @@ -156,7 +156,7 @@ void test_rebase_inmemory__no_common_ancestor(void) cl_git_pass(git_rebase_finish(rebase, signature)); - git_oid_fromstr(&expected_final_id, "71e7ee8d4fe7d8bf0d107355197e0a953dfdb7f3"); + git_oid__fromstr(&expected_final_id, "71e7ee8d4fe7d8bf0d107355197e0a953dfdb7f3", GIT_OID_SHA1); cl_assert_equal_oid(&expected_final_id, &commit_id); git_annotated_commit_free(branch_head); @@ -178,7 +178,7 @@ void test_rebase_inmemory__with_directories(void) opts.inmemory = true; - git_oid_fromstr(&tree_id, "a4d6d9c3d57308fd8e320cf2525bae8f1adafa57"); + git_oid__fromstr(&tree_id, "a4d6d9c3d57308fd8e320cf2525bae8f1adafa57", GIT_OID_SHA1); cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/deep_gravy")); cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/veal")); diff --git a/tests/libgit2/rebase/iterator.c b/tests/libgit2/rebase/iterator.c index a120f28ac..79e9f3e58 100644 --- a/tests/libgit2/rebase/iterator.c +++ b/tests/libgit2/rebase/iterator.c @@ -30,11 +30,11 @@ static void test_operations(git_rebase *rebase, size_t expected_current) git_oid expected_oid[5]; git_rebase_operation *operation; - git_oid_fromstr(&expected_oid[0], "da9c51a23d02d931a486f45ad18cda05cf5d2b94"); - git_oid_fromstr(&expected_oid[1], "8d1f13f93c4995760ac07d129246ac1ff64c0be9"); - git_oid_fromstr(&expected_oid[2], "3069cc907e6294623e5917ef6de663928c1febfb"); - git_oid_fromstr(&expected_oid[3], "588e5d2f04d49707fe4aab865e1deacaf7ef6787"); - git_oid_fromstr(&expected_oid[4], "b146bd7608eac53d9bf9e1a6963543588b555c64"); + git_oid__fromstr(&expected_oid[0], "da9c51a23d02d931a486f45ad18cda05cf5d2b94", GIT_OID_SHA1); + git_oid__fromstr(&expected_oid[1], "8d1f13f93c4995760ac07d129246ac1ff64c0be9", GIT_OID_SHA1); + git_oid__fromstr(&expected_oid[2], "3069cc907e6294623e5917ef6de663928c1febfb", GIT_OID_SHA1); + git_oid__fromstr(&expected_oid[3], "588e5d2f04d49707fe4aab865e1deacaf7ef6787", GIT_OID_SHA1); + git_oid__fromstr(&expected_oid[4], "b146bd7608eac53d9bf9e1a6963543588b555c64", GIT_OID_SHA1); cl_assert_equal_i(expected_count, git_rebase_operation_entrycount(rebase)); cl_assert_equal_i(expected_current, git_rebase_operation_current(rebase)); @@ -78,7 +78,7 @@ static void test_iterator(bool inmemory) NULL, NULL)); test_operations(rebase, 0); - git_oid_fromstr(&expected_id, "776e4c48922799f903f03f5f6e51da8b01e4cce0"); + git_oid__fromstr(&expected_id, "776e4c48922799f903f03f5f6e51da8b01e4cce0", GIT_OID_SHA1); cl_assert_equal_oid(&expected_id, &commit_id); cl_git_pass(git_rebase_next(&rebase_operation, rebase)); @@ -86,7 +86,7 @@ static void test_iterator(bool inmemory) NULL, NULL)); test_operations(rebase, 1); - git_oid_fromstr(&expected_id, "ba1f9b4fd5cf8151f7818be2111cc0869f1eb95a"); + git_oid__fromstr(&expected_id, "ba1f9b4fd5cf8151f7818be2111cc0869f1eb95a", GIT_OID_SHA1); cl_assert_equal_oid(&expected_id, &commit_id); cl_git_pass(git_rebase_next(&rebase_operation, rebase)); @@ -94,7 +94,7 @@ static void test_iterator(bool inmemory) NULL, NULL)); test_operations(rebase, 2); - git_oid_fromstr(&expected_id, "948b12fe18b84f756223a61bece4c307787cd5d4"); + git_oid__fromstr(&expected_id, "948b12fe18b84f756223a61bece4c307787cd5d4", GIT_OID_SHA1); cl_assert_equal_oid(&expected_id, &commit_id); if (!inmemory) { @@ -107,7 +107,7 @@ static void test_iterator(bool inmemory) NULL, NULL)); test_operations(rebase, 3); - git_oid_fromstr(&expected_id, "d9d5d59d72c9968687f9462578d79878cd80e781"); + git_oid__fromstr(&expected_id, "d9d5d59d72c9968687f9462578d79878cd80e781", GIT_OID_SHA1); cl_assert_equal_oid(&expected_id, &commit_id); cl_git_pass(git_rebase_next(&rebase_operation, rebase)); @@ -115,7 +115,7 @@ static void test_iterator(bool inmemory) NULL, NULL)); test_operations(rebase, 4); - git_oid_fromstr(&expected_id, "9cf383c0a125d89e742c5dec58ed277dd07588b3"); + git_oid__fromstr(&expected_id, "9cf383c0a125d89e742c5dec58ed277dd07588b3", GIT_OID_SHA1); cl_assert_equal_oid(&expected_id, &commit_id); cl_git_fail(error = git_rebase_next(&rebase_operation, rebase)); diff --git a/tests/libgit2/rebase/merge.c b/tests/libgit2/rebase/merge.c index 5f730f750..870c3ea2f 100644 --- a/tests/libgit2/rebase/merge.c +++ b/tests/libgit2/rebase/merge.c @@ -46,8 +46,8 @@ void test_rebase_merge__next(void) git_oid pick_id, file1_id; git_oid master_id, beef_id; - git_oid_fromstr(&master_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00"); - git_oid_fromstr(&beef_id, "b146bd7608eac53d9bf9e1a6963543588b555c64"); + git_oid__fromstr(&master_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00", GIT_OID_SHA1); + git_oid__fromstr(&beef_id, "b146bd7608eac53d9bf9e1a6963543588b555c64", GIT_OID_SHA1); cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/beef")); cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/master")); @@ -65,7 +65,7 @@ void test_rebase_merge__next(void) cl_git_pass(git_rebase_next(&rebase_operation, rebase)); - git_oid_fromstr(&pick_id, "da9c51a23d02d931a486f45ad18cda05cf5d2b94"); + git_oid__fromstr(&pick_id, "da9c51a23d02d931a486f45ad18cda05cf5d2b94", GIT_OID_SHA1); cl_assert_equal_i(GIT_REBASE_OPERATION_PICK, rebase_operation->type); cl_assert_equal_oid(&pick_id, &rebase_operation->id); @@ -78,7 +78,7 @@ void test_rebase_merge__next(void) cl_assert_equal_s("beef.txt", status_entry->head_to_index->new_file.path); - git_oid_fromstr(&file1_id, "8d95ea62e621f1d38d230d9e7d206e41096d76af"); + git_oid__fromstr(&file1_id, "8d95ea62e621f1d38d230d9e7d206e41096d76af", GIT_OID_SHA1); cl_assert_equal_oid(&file1_id, &status_entry->head_to_index->new_file.id); git_status_list_free(status_list); @@ -129,7 +129,7 @@ void test_rebase_merge__next_with_conflicts(void) cl_git_pass(git_rebase_next(&rebase_operation, rebase)); - git_oid_fromstr(&pick_id, "33f915f9e4dbd9f4b24430e48731a59b45b15500"); + git_oid__fromstr(&pick_id, "33f915f9e4dbd9f4b24430e48731a59b45b15500", GIT_OID_SHA1); cl_assert_equal_i(GIT_REBASE_OPERATION_PICK, rebase_operation->type); cl_assert_equal_oid(&pick_id, &rebase_operation->id); @@ -230,11 +230,11 @@ void test_rebase_merge__commit(void) cl_git_pass(git_commit_lookup(&commit, repo, &commit_id)); - git_oid_fromstr(&parent_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00"); + git_oid__fromstr(&parent_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00", GIT_OID_SHA1); cl_assert_equal_i(1, git_commit_parentcount(commit)); cl_assert_equal_oid(&parent_id, git_commit_parent_id(commit, 0)); - git_oid_fromstr(&tree_id, "4461379789c777d2a6c1f2ee0e9d6c86731b9992"); + git_oid__fromstr(&tree_id, "4461379789c777d2a6c1f2ee0e9d6c86731b9992", GIT_OID_SHA1); cl_assert_equal_oid(&tree_id, git_commit_tree_id(commit)); cl_assert_equal_s(NULL, git_commit_message_encoding(commit)); @@ -275,8 +275,8 @@ void test_rebase_merge__commit_with_id(void) git_reflog *reflog; const git_reflog_entry *reflog_entry; - cl_git_pass(git_oid_fromstr(&branch_id, "b146bd7608eac53d9bf9e1a6963543588b555c64")); - cl_git_pass(git_oid_fromstr(&upstream_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00")); + cl_git_pass(git_oid__fromstr(&branch_id, "b146bd7608eac53d9bf9e1a6963543588b555c64", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&upstream_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00", GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&branch_head, repo, &branch_id)); cl_git_pass(git_annotated_commit_lookup(&upstream_head, repo, &upstream_id)); @@ -289,11 +289,11 @@ void test_rebase_merge__commit_with_id(void) cl_git_pass(git_commit_lookup(&commit, repo, &commit_id)); - git_oid_fromstr(&parent_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00"); + git_oid__fromstr(&parent_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00", GIT_OID_SHA1); cl_assert_equal_i(1, git_commit_parentcount(commit)); cl_assert_equal_oid(&parent_id, git_commit_parent_id(commit, 0)); - git_oid_fromstr(&tree_id, "4461379789c777d2a6c1f2ee0e9d6c86731b9992"); + git_oid__fromstr(&tree_id, "4461379789c777d2a6c1f2ee0e9d6c86731b9992", GIT_OID_SHA1); cl_assert_equal_oid(&tree_id, git_commit_tree_id(commit)); cl_assert_equal_s(NULL, git_commit_message_encoding(commit)); @@ -551,8 +551,8 @@ void test_rebase_merge__finish_with_ids(void) const git_reflog_entry *reflog_entry; int error; - cl_git_pass(git_oid_fromstr(&branch_id, "d616d97082eb7bb2dc6f180a7cca940993b7a56f")); - cl_git_pass(git_oid_fromstr(&upstream_id, "f87d14a4a236582a0278a916340a793714256864")); + cl_git_pass(git_oid__fromstr(&branch_id, "d616d97082eb7bb2dc6f180a7cca940993b7a56f", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&upstream_id, "f87d14a4a236582a0278a916340a793714256864", GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&branch_head, repo, &branch_id)); cl_git_pass(git_annotated_commit_lookup(&upstream_head, repo, &upstream_id)); @@ -627,7 +627,7 @@ void test_rebase_merge__no_common_ancestor(void) cl_git_pass(git_rebase_finish(rebase, signature)); - git_oid_fromstr(&expected_final_id, "71e7ee8d4fe7d8bf0d107355197e0a953dfdb7f3"); + git_oid__fromstr(&expected_final_id, "71e7ee8d4fe7d8bf0d107355197e0a953dfdb7f3", GIT_OID_SHA1); cl_assert_equal_oid(&expected_final_id, &commit_id); git_annotated_commit_free(branch_head); @@ -823,7 +823,7 @@ void test_rebase_merge__with_directories(void) git_oid commit_id, tree_id; git_commit *commit; - git_oid_fromstr(&tree_id, "a4d6d9c3d57308fd8e320cf2525bae8f1adafa57"); + git_oid__fromstr(&tree_id, "a4d6d9c3d57308fd8e320cf2525bae8f1adafa57", GIT_OID_SHA1); cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/deep_gravy")); cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/veal")); diff --git a/tests/libgit2/rebase/setup.c b/tests/libgit2/rebase/setup.c index 34d5edbf6..ac0d087ea 100644 --- a/tests/libgit2/rebase/setup.c +++ b/tests/libgit2/rebase/setup.c @@ -74,7 +74,7 @@ void test_rebase_setup__merge(void) cl_assert_equal_i(GIT_REPOSITORY_STATE_REBASE_MERGE, git_repository_state(repo)); - git_oid_fromstr(&head_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00"); + git_oid__fromstr(&head_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00", GIT_OID_SHA1); cl_git_pass(git_repository_head(&head, repo)); cl_git_pass(git_reference_peel((git_object **)&head_commit, head, GIT_OBJECT_COMMIT)); cl_assert_equal_oid(&head_id, git_commit_id(head_commit)); @@ -120,7 +120,7 @@ void test_rebase_setup__merge_root(void) cl_git_pass(git_rebase_init(&rebase, repo, branch_head, NULL, onto_head, NULL)); - git_oid_fromstr(&head_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00"); + git_oid__fromstr(&head_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00", GIT_OID_SHA1); cl_git_pass(git_repository_head(&head, repo)); cl_git_pass(git_reference_peel((git_object **)&head_commit, head, GIT_OBJECT_COMMIT)); cl_assert_equal_oid(&head_id, git_commit_id(head_commit)); @@ -170,7 +170,7 @@ void test_rebase_setup__merge_onto_and_upstream(void) cl_git_pass(git_rebase_init(&rebase, repo, branch1_head, branch2_head, onto_head, NULL)); - git_oid_fromstr(&head_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00"); + git_oid__fromstr(&head_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00", GIT_OID_SHA1); cl_git_pass(git_repository_head(&head, repo)); cl_git_pass(git_reference_peel((git_object **)&head_commit, head, GIT_OBJECT_COMMIT)); cl_assert_equal_oid(&head_id, git_commit_id(head_commit)); @@ -224,7 +224,7 @@ void test_rebase_setup__merge_onto_upstream_and_branch(void) cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, onto_head, NULL)); - git_oid_fromstr(&head_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00"); + git_oid__fromstr(&head_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00", GIT_OID_SHA1); cl_git_pass(git_repository_head(&head, repo)); cl_git_pass(git_reference_peel((git_object **)&head_commit, head, GIT_OBJECT_COMMIT)); cl_assert_equal_oid(&head_id, git_commit_id(head_commit)); @@ -272,9 +272,9 @@ void test_rebase_setup__merge_onto_upstream_and_branch_by_id(void) cl_git_pass(git_repository_set_head(repo, "refs/heads/beef")); cl_git_pass(git_checkout_head(repo, &checkout_opts)); - cl_git_pass(git_oid_fromstr(&upstream_id, "f87d14a4a236582a0278a916340a793714256864")); - cl_git_pass(git_oid_fromstr(&branch_id, "d616d97082eb7bb2dc6f180a7cca940993b7a56f")); - cl_git_pass(git_oid_fromstr(&onto_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00")); + cl_git_pass(git_oid__fromstr(&upstream_id, "f87d14a4a236582a0278a916340a793714256864", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&branch_id, "d616d97082eb7bb2dc6f180a7cca940993b7a56f", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&onto_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00", GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&upstream_head, repo, &upstream_id)); cl_git_pass(git_annotated_commit_lookup(&branch_head, repo, &branch_id)); @@ -282,7 +282,7 @@ void test_rebase_setup__merge_onto_upstream_and_branch_by_id(void) cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, onto_head, NULL)); - git_oid_fromstr(&head_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00"); + git_oid__fromstr(&head_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00", GIT_OID_SHA1); cl_git_pass(git_repository_head(&head, repo)); cl_git_pass(git_reference_peel((git_object **)&head_commit, head, GIT_OBJECT_COMMIT)); cl_assert_equal_oid(&head_id, git_commit_id(head_commit)); @@ -328,7 +328,7 @@ void test_rebase_setup__branch_with_merges(void) cl_assert_equal_i(GIT_REPOSITORY_STATE_REBASE_MERGE, git_repository_state(repo)); - git_oid_fromstr(&head_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00"); + git_oid__fromstr(&head_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00", GIT_OID_SHA1); cl_git_pass(git_repository_head(&head, repo)); cl_git_pass(git_reference_peel((git_object **)&head_commit, head, GIT_OBJECT_COMMIT)); cl_assert_equal_oid(&head_id, git_commit_id(head_commit)); @@ -376,7 +376,7 @@ void test_rebase_setup__orphan_branch(void) cl_assert_equal_i(GIT_REPOSITORY_STATE_REBASE_MERGE, git_repository_state(repo)); - git_oid_fromstr(&head_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00"); + git_oid__fromstr(&head_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00", GIT_OID_SHA1); cl_git_pass(git_repository_head(&head, repo)); cl_git_pass(git_reference_peel((git_object **)&head_commit, head, GIT_OBJECT_COMMIT)); cl_assert_equal_oid(&head_id, git_commit_id(head_commit)); @@ -427,7 +427,7 @@ void test_rebase_setup__merge_null_branch_uses_HEAD(void) cl_assert_equal_i(GIT_REPOSITORY_STATE_REBASE_MERGE, git_repository_state(repo)); - git_oid_fromstr(&head_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00"); + git_oid__fromstr(&head_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00", GIT_OID_SHA1); cl_git_pass(git_repository_head(&head, repo)); cl_git_pass(git_reference_peel((git_object **)&head_commit, head, GIT_OBJECT_COMMIT)); cl_assert_equal_oid(&head_id, git_commit_id(head_commit)); @@ -465,7 +465,7 @@ void test_rebase_setup__merge_from_detached(void) cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/master")); - cl_git_pass(git_oid_fromstr(&branch_id, "b146bd7608eac53d9bf9e1a6963543588b555c64")); + cl_git_pass(git_oid__fromstr(&branch_id, "b146bd7608eac53d9bf9e1a6963543588b555c64", GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_lookup(&branch_head, repo, &branch_id)); cl_git_pass(git_annotated_commit_from_ref(&upstream_head, repo, upstream_ref)); @@ -474,7 +474,7 @@ void test_rebase_setup__merge_from_detached(void) cl_assert_equal_i(GIT_REPOSITORY_STATE_REBASE_MERGE, git_repository_state(repo)); - git_oid_fromstr(&head_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00"); + git_oid__fromstr(&head_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00", GIT_OID_SHA1); cl_git_pass(git_repository_head(&head, repo)); cl_git_pass(git_reference_peel((git_object **)&head_commit, head, GIT_OBJECT_COMMIT)); cl_assert_equal_oid(&head_id, git_commit_id(head_commit)); @@ -513,7 +513,7 @@ void test_rebase_setup__merge_branch_by_id(void) cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/beef")); - cl_git_pass(git_oid_fromstr(&upstream_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00")); + cl_git_pass(git_oid__fromstr(&upstream_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00", GIT_OID_SHA1)); cl_git_pass(git_annotated_commit_from_ref(&branch_head, repo, branch_ref)); cl_git_pass(git_annotated_commit_lookup(&upstream_head, repo, &upstream_id)); @@ -522,7 +522,7 @@ void test_rebase_setup__merge_branch_by_id(void) cl_assert_equal_i(GIT_REPOSITORY_STATE_REBASE_MERGE, git_repository_state(repo)); - git_oid_fromstr(&head_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00"); + git_oid__fromstr(&head_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00", GIT_OID_SHA1); cl_git_pass(git_repository_head(&head, repo)); cl_git_pass(git_reference_peel((git_object **)&head_commit, head, GIT_OBJECT_COMMIT)); cl_assert_equal_oid(&head_id, git_commit_id(head_commit)); diff --git a/tests/libgit2/rebase/sign.c b/tests/libgit2/rebase/sign.c index 4064cf79b..69bb1c6f9 100644 --- a/tests/libgit2/rebase/sign.c +++ b/tests/libgit2/rebase/sign.c @@ -70,7 +70,7 @@ committer Rebaser 1405694510 +0000\n"; cl_git_pass(git_rebase_next(&rebase_operation, rebase)); cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature, NULL, NULL)); - git_oid_fromstr(&expected_id, "129183968a65abd6c52da35bff43325001bfc630"); + git_oid__fromstr(&expected_id, "129183968a65abd6c52da35bff43325001bfc630", GIT_OID_SHA1); cl_assert_equal_oid(&expected_id, &commit_id); cl_git_pass(git_commit_lookup(&commit, repo, &commit_id)); @@ -178,7 +178,7 @@ gpgsig -----BEGIN PGP SIGNATURE-----\n\ cl_git_pass(git_rebase_next(&rebase_operation, rebase)); cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature, NULL, NULL)); - git_oid_fromstr(&expected_id, "bf78348e45c8286f52b760f1db15cb6da030f2ef"); + git_oid__fromstr(&expected_id, "bf78348e45c8286f52b760f1db15cb6da030f2ef", GIT_OID_SHA1); cl_assert_equal_oid(&expected_id, &commit_id); cl_git_pass(git_commit_lookup(&commit, repo, &commit_id)); @@ -300,7 +300,7 @@ committer Rebaser 1405694510 +0000\n"; cl_git_pass(git_rebase_next(&rebase_operation, rebase)); cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature, NULL, NULL)); - git_oid_fromstr(&expected_id, "129183968a65abd6c52da35bff43325001bfc630"); + git_oid__fromstr(&expected_id, "129183968a65abd6c52da35bff43325001bfc630", GIT_OID_SHA1); cl_assert_equal_oid(&expected_id, &commit_id); cl_git_pass(git_commit_lookup(&commit, repo, &commit_id)); @@ -398,7 +398,7 @@ gpgsig -----BEGIN PGP SIGNATURE-----\n\ cl_git_pass(git_rebase_next(&rebase_operation, rebase)); cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature, NULL, NULL)); - git_oid_fromstr(&expected_id, "bf78348e45c8286f52b760f1db15cb6da030f2ef"); + git_oid__fromstr(&expected_id, "bf78348e45c8286f52b760f1db15cb6da030f2ef", GIT_OID_SHA1); cl_assert_equal_oid(&expected_id, &commit_id); cl_git_pass(git_commit_lookup(&commit, repo, &commit_id)); @@ -473,7 +473,7 @@ magicsig magic word: pretty please\n"; cl_git_pass(git_rebase_next(&rebase_operation, rebase)); cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature, NULL, NULL)); - git_oid_fromstr(&expected_id, "f46a4a8d26ae411b02aa61b7d69576627f4a1e1c"); + git_oid__fromstr(&expected_id, "f46a4a8d26ae411b02aa61b7d69576627f4a1e1c", GIT_OID_SHA1); cl_assert_equal_oid(&expected_id, &commit_id); cl_git_pass(git_commit_lookup(&commit, repo, &commit_id)); diff --git a/tests/libgit2/refs/basic.c b/tests/libgit2/refs/basic.c index 32742f9cc..5e41ca074 100644 --- a/tests/libgit2/refs/basic.c +++ b/tests/libgit2/refs/basic.c @@ -53,7 +53,7 @@ void test_refs_basic__longpaths(void) git_reference *one = NULL, *two = NULL; git_oid id; - cl_git_pass(git_oid_fromstr(&id, "099fabac3a9ea935598528c27f866e34089c2eff")); + cl_git_pass(git_oid__fromstr(&id, "099fabac3a9ea935598528c27f866e34089c2eff", GIT_OID_SHA1)); base = git_repository_path(g_repo); base_len = git_utf8_char_length(base, strlen(base)); diff --git a/tests/libgit2/refs/branches/delete.c b/tests/libgit2/refs/branches/delete.c index 27995f9e2..6b3d507a8 100644 --- a/tests/libgit2/refs/branches/delete.c +++ b/tests/libgit2/refs/branches/delete.c @@ -14,7 +14,7 @@ void test_refs_branches_delete__initialize(void) repo = cl_git_sandbox_init("testrepo.git"); - cl_git_pass(git_oid_fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644")); + cl_git_pass(git_oid__fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644", GIT_OID_SHA1)); cl_git_pass(git_reference_create(&fake_remote, repo, "refs/remotes/nulltoken/master", &id, 0, NULL)); } @@ -119,7 +119,7 @@ void test_refs_branches_delete__removes_reflog(void) { git_reference *branch; git_reflog *log; - git_oid oidzero = {{0}}; + git_oid oidzero = GIT_OID_SHA1_ZERO; git_signature *sig; /* Ensure the reflog has at least one entry */ @@ -150,14 +150,14 @@ void test_refs_branches_delete__removes_empty_folders(void) git_reference *branch; git_reflog *log; - git_oid oidzero = {{0}}; + git_oid oidzero = GIT_OID_SHA1_ZERO; git_signature *sig; git_str ref_folder = GIT_STR_INIT; git_str reflog_folder = GIT_STR_INIT; /* Create a new branch with a nested name */ - cl_git_pass(git_oid_fromstr(&commit_id, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750")); + cl_git_pass(git_oid__fromstr(&commit_id, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", GIT_OID_SHA1)); cl_git_pass(git_commit_lookup(&commit, repo, &commit_id)); cl_git_pass(git_branch_create(&branch, repo, "some/deep/ref", commit, 0)); git_commit_free(commit); diff --git a/tests/libgit2/refs/branches/iterator.c b/tests/libgit2/refs/branches/iterator.c index e086681e5..a295d553b 100644 --- a/tests/libgit2/refs/branches/iterator.c +++ b/tests/libgit2/refs/branches/iterator.c @@ -11,7 +11,7 @@ void test_refs_branches_iterator__initialize(void) cl_fixture_sandbox("testrepo.git"); cl_git_pass(git_repository_open(&repo, "testrepo.git")); - cl_git_pass(git_oid_fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644")); + cl_git_pass(git_oid__fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644", GIT_OID_SHA1)); cl_git_pass(git_reference_create(&fake_remote, repo, "refs/remotes/nulltoken/master", &id, 0, NULL)); } diff --git a/tests/libgit2/refs/create.c b/tests/libgit2/refs/create.c index 01eb62a52..1dafcf61a 100644 --- a/tests/libgit2/refs/create.c +++ b/tests/libgit2/refs/create.c @@ -34,7 +34,7 @@ void test_refs_create__symbolic(void) const char *new_head_tracker = "ANOTHER_HEAD_TRACKER"; - git_oid_fromstr(&id, current_master_tip); + git_oid__fromstr(&id, current_master_tip, GIT_OID_SHA1); /* Create and write the new symbolic reference */ cl_git_pass(git_reference_symbolic_create(&new_reference, g_repo, new_head_tracker, current_head_target, 0, NULL)); @@ -77,7 +77,7 @@ void test_refs_create__symbolic_with_arbitrary_content(void) const char *new_head_tracker = "ANOTHER_HEAD_TRACKER"; const char *arbitrary_target = "ARBITRARY DATA"; - git_oid_fromstr(&id, current_master_tip); + git_oid__fromstr(&id, current_master_tip, GIT_OID_SHA1); /* Attempt to create symbolic ref with arbitrary data in target * fails by default @@ -124,7 +124,7 @@ void test_refs_create__deep_symbolic(void) const char *new_head_tracker = "deep/rooted/tracker"; - git_oid_fromstr(&id, current_master_tip); + git_oid__fromstr(&id, current_master_tip, GIT_OID_SHA1); cl_git_pass(git_reference_symbolic_create(&new_reference, g_repo, new_head_tracker, current_head_target, 0, NULL)); cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, new_head_tracker)); @@ -145,7 +145,7 @@ void test_refs_create__oid(void) const char *new_head = "refs/heads/new-head"; - git_oid_fromstr(&id, current_master_tip); + git_oid__fromstr(&id, current_master_tip, GIT_OID_SHA1); /* Create and write the new object id reference */ cl_git_pass(git_reference_create(&new_reference, g_repo, new_head, &id, 0, NULL)); @@ -180,7 +180,7 @@ void test_refs_create__oid_unknown_succeeds_without_strict(void) const char *new_head = "refs/heads/new-head"; - git_oid_fromstr(&id, "deadbeef3f795b2b4353bcce3a527ad0a4f7f644"); + git_oid__fromstr(&id, "deadbeef3f795b2b4353bcce3a527ad0a4f7f644", GIT_OID_SHA1); cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_STRICT_OBJECT_CREATION, 0)); @@ -201,7 +201,7 @@ void test_refs_create__oid_unknown_fails_by_default(void) const char *new_head = "refs/heads/new-head"; - git_oid_fromstr(&id, "deadbeef3f795b2b4353bcce3a527ad0a4f7f644"); + git_oid__fromstr(&id, "deadbeef3f795b2b4353bcce3a527ad0a4f7f644", GIT_OID_SHA1); /* Create and write the new object id reference */ cl_git_fail(git_reference_create(&new_reference, g_repo, new_head, &id, 0, NULL)); @@ -215,7 +215,7 @@ void test_refs_create__propagate_eexists(void) git_oid oid; /* Make sure it works for oid and for symbolic both */ - cl_git_pass(git_oid_fromstr(&oid, current_master_tip)); + cl_git_pass(git_oid__fromstr(&oid, current_master_tip, GIT_OID_SHA1)); cl_git_fail_with(GIT_EEXISTS, git_reference_create(NULL, g_repo, current_head_target, &oid, false, NULL)); cl_git_fail_with(GIT_EEXISTS, git_reference_symbolic_create(NULL, g_repo, "HEAD", current_head_target, false, NULL)); } @@ -227,7 +227,7 @@ void test_refs_create__existing_dir_propagates_edirectory(void) const char *dir_head = "refs/heads/new-dir/new-head", *fail_head = "refs/heads/new-dir"; - git_oid_fromstr(&id, current_master_tip); + git_oid__fromstr(&id, current_master_tip, GIT_OID_SHA1); /* Create and write the new object id reference */ cl_git_pass(git_reference_create(&new_reference, g_repo, dir_head, &id, 1, NULL)); @@ -242,7 +242,7 @@ static void test_invalid_name(const char *name) git_reference *new_reference; git_oid id; - git_oid_fromstr(&id, current_master_tip); + git_oid__fromstr(&id, current_master_tip, GIT_OID_SHA1); cl_assert_equal_i(GIT_EINVALIDSPEC, git_reference_create( &new_reference, g_repo, name, &id, 0, NULL)); @@ -272,7 +272,7 @@ static void test_win32_name(const char *name) git_oid id; int ret; - git_oid_fromstr(&id, current_master_tip); + git_oid__fromstr(&id, current_master_tip, GIT_OID_SHA1); ret = git_reference_create(&new_reference, g_repo, name, &id, 0, NULL); @@ -314,7 +314,7 @@ static void count_fsyncs(size_t *create_count, size_t *compress_count) p_fsync__cnt = 0; - git_oid_fromstr(&id, current_master_tip); + git_oid__fromstr(&id, current_master_tip, GIT_OID_SHA1); cl_git_pass(git_reference_create(&ref, g_repo, "refs/heads/fsync_test", &id, 0, "log message")); git_reference_free(ref); diff --git a/tests/libgit2/refs/delete.c b/tests/libgit2/refs/delete.c index 42cc534b5..edb521f4a 100644 --- a/tests/libgit2/refs/delete.c +++ b/tests/libgit2/refs/delete.c @@ -63,7 +63,7 @@ void test_refs_delete__packed_only(void) git_oid id; const char *new_ref = "refs/heads/new_ref"; - git_oid_fromstr(&id, current_master_tip); + git_oid__fromstr(&id, current_master_tip, GIT_OID_SHA1); /* Create and write the new object id reference */ cl_git_pass(git_reference_create(&ref, g_repo, new_ref, &id, 0, NULL)); diff --git a/tests/libgit2/refs/foreachglob.c b/tests/libgit2/refs/foreachglob.c index b208a95a2..a586ca08c 100644 --- a/tests/libgit2/refs/foreachglob.c +++ b/tests/libgit2/refs/foreachglob.c @@ -11,7 +11,7 @@ void test_refs_foreachglob__initialize(void) cl_fixture_sandbox("testrepo.git"); cl_git_pass(git_repository_open(&repo, "testrepo.git")); - cl_git_pass(git_oid_fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644")); + cl_git_pass(git_oid__fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644", GIT_OID_SHA1)); cl_git_pass(git_reference_create(&fake_remote, repo, "refs/remotes/nulltoken/master", &id, 0, NULL)); } diff --git a/tests/libgit2/refs/iterator.c b/tests/libgit2/refs/iterator.c index a4f9e62ec..f40d35d11 100644 --- a/tests/libgit2/refs/iterator.c +++ b/tests/libgit2/refs/iterator.c @@ -1,6 +1,7 @@ #include "clar_libgit2.h" #include "refs.h" #include "vector.h" +#include "odb.h" static git_repository *repo; @@ -126,7 +127,7 @@ void test_refs_iterator__empty(void) git_reference *ref; git_repository *empty; - cl_git_pass(git_odb_new(&odb)); + cl_git_pass(git_odb__new(&odb, NULL)); cl_git_pass(git_repository_wrap_odb(&empty, odb)); cl_git_pass(git_reference_iterator_new(&iter, empty)); diff --git a/tests/libgit2/refs/lookup.c b/tests/libgit2/refs/lookup.c index 01e956de2..2b8be77f8 100644 --- a/tests/libgit2/refs/lookup.c +++ b/tests/libgit2/refs/lookup.c @@ -43,7 +43,7 @@ void test_refs_lookup__oid(void) git_oid tag, expected; cl_git_pass(git_reference_name_to_id(&tag, g_repo, "refs/tags/point_to_blob")); - cl_git_pass(git_oid_fromstr(&expected, "1385f264afb75a56a5bec74243be9b367ba4ca08")); + cl_git_pass(git_oid__fromstr(&expected, "1385f264afb75a56a5bec74243be9b367ba4ca08", GIT_OID_SHA1)); cl_assert_equal_oid(&expected, &tag); } diff --git a/tests/libgit2/refs/peel.c b/tests/libgit2/refs/peel.c index 38f3465a0..fefd2d260 100644 --- a/tests/libgit2/refs/peel.c +++ b/tests/libgit2/refs/peel.c @@ -32,7 +32,7 @@ static void assert_peel_generic( cl_git_pass(git_reference_peel(&peeled, ref, requested_type)); - cl_git_pass(git_oid_fromstr(&expected_oid, expected_sha)); + cl_git_pass(git_oid__fromstr(&expected_oid, expected_sha, GIT_OID_SHA1)); cl_assert_equal_oid(&expected_oid, git_object_id(peeled)); cl_assert_equal_i(expected_type, git_object_type(peeled)); diff --git a/tests/libgit2/refs/races.c b/tests/libgit2/refs/races.c index 476789358..bf46b760e 100644 --- a/tests/libgit2/refs/races.c +++ b/tests/libgit2/refs/races.c @@ -27,8 +27,8 @@ void test_refs_races__create_matching_zero_old(void) git_reference *ref; git_oid id, zero_id; - git_oid_fromstr(&id, commit_id); - git_oid_fromstr(&zero_id, "0000000000000000000000000000000000000000"); + git_oid__fromstr(&id, commit_id, GIT_OID_SHA1); + git_oid__fromstr(&zero_id, "0000000000000000000000000000000000000000", GIT_OID_SHA1); cl_git_fail(git_reference_create_matching(&ref, g_repo, refname, &id, 1, &zero_id, NULL)); git_reference_free(ref); @@ -45,8 +45,8 @@ void test_refs_races__create_matching(void) git_reference *ref, *ref2, *ref3; git_oid id, other_id; - git_oid_fromstr(&id, commit_id); - git_oid_fromstr(&other_id, other_commit_id); + git_oid__fromstr(&id, commit_id, GIT_OID_SHA1); + git_oid__fromstr(&other_id, other_commit_id, GIT_OID_SHA1); cl_git_fail_with(GIT_EMODIFIED, git_reference_create_matching(&ref, g_repo, refname, &other_id, 1, &other_id, NULL)); @@ -64,8 +64,8 @@ void test_refs_races__symbolic_create_matching(void) git_reference *ref, *ref2, *ref3; git_oid id, other_id; - git_oid_fromstr(&id, commit_id); - git_oid_fromstr(&other_id, other_commit_id); + git_oid__fromstr(&id, commit_id, GIT_OID_SHA1); + git_oid__fromstr(&other_id, other_commit_id, GIT_OID_SHA1); cl_git_fail_with(GIT_EMODIFIED, git_reference_symbolic_create_matching(&ref, g_repo, "HEAD", other_refname, 1, other_refname, NULL)); @@ -83,8 +83,8 @@ void test_refs_races__delete(void) git_reference *ref, *ref2; git_oid id, other_id; - git_oid_fromstr(&id, commit_id); - git_oid_fromstr(&other_id, other_commit_id); + git_oid__fromstr(&id, commit_id, GIT_OID_SHA1); + git_oid__fromstr(&other_id, other_commit_id, GIT_OID_SHA1); /* We can delete a value that matches */ cl_git_pass(git_reference_lookup(&ref, g_repo, refname)); @@ -116,8 +116,8 @@ void test_refs_races__switch_oid_to_symbolic(void) git_reference *ref, *ref2, *ref3; git_oid id, other_id; - git_oid_fromstr(&id, commit_id); - git_oid_fromstr(&other_id, other_commit_id); + git_oid__fromstr(&id, commit_id, GIT_OID_SHA1); + git_oid__fromstr(&other_id, other_commit_id, GIT_OID_SHA1); /* Removing a direct ref when it's currently symbolic should fail */ cl_git_pass(git_reference_lookup(&ref, g_repo, refname)); @@ -145,8 +145,8 @@ void test_refs_races__switch_symbolic_to_oid(void) git_reference *ref, *ref2, *ref3; git_oid id, other_id; - git_oid_fromstr(&id, commit_id); - git_oid_fromstr(&other_id, other_commit_id); + git_oid__fromstr(&id, commit_id, GIT_OID_SHA1); + git_oid__fromstr(&other_id, other_commit_id, GIT_OID_SHA1); /* Removing a symbolic ref when it's currently direct should fail */ cl_git_pass(git_reference_lookup(&ref, g_repo, "refs/symref")); diff --git a/tests/libgit2/refs/read.c b/tests/libgit2/refs/read.c index a622c770b..7253cf137 100644 --- a/tests/libgit2/refs/read.c +++ b/tests/libgit2/refs/read.c @@ -82,7 +82,7 @@ void test_refs_read__symbolic(void) cl_assert(object != NULL); cl_assert(git_object_type(object) == GIT_OBJECT_COMMIT); - git_oid_fromstr(&id, current_master_tip); + git_oid__fromstr(&id, current_master_tip, GIT_OID_SHA1); cl_assert_equal_oid(&id, git_object_id(object)); git_object_free(object); @@ -110,7 +110,7 @@ void test_refs_read__nested_symbolic(void) cl_assert(object != NULL); cl_assert(git_object_type(object) == GIT_OBJECT_COMMIT); - git_oid_fromstr(&id, current_master_tip); + git_oid__fromstr(&id, current_master_tip, GIT_OID_SHA1); cl_assert_equal_oid(&id, git_object_id(object)); git_object_free(object); diff --git a/tests/libgit2/refs/reflog/drop.c b/tests/libgit2/refs/reflog/drop.c index 916bd9933..2d7193380 100644 --- a/tests/libgit2/refs/reflog/drop.c +++ b/tests/libgit2/refs/reflog/drop.c @@ -70,7 +70,7 @@ void test_refs_reflog_drop__can_drop_the_oldest_entry(void) cl_assert_equal_sz(entrycount - 1, git_reflog_entrycount(g_reflog)); entry = git_reflog_entry_byindex(g_reflog, entrycount - 2); - cl_assert(git_oid_streq(&entry->oid_old, GIT_OID_HEX_ZERO) != 0); + cl_assert(git_oid_streq(&entry->oid_old, GIT_OID_SHA1_HEXZERO) != 0); } void test_refs_reflog_drop__can_drop_the_oldest_entry_and_rewrite_the_log_history(void) @@ -83,7 +83,7 @@ void test_refs_reflog_drop__can_drop_the_oldest_entry_and_rewrite_the_log_histor cl_assert_equal_sz(entrycount - 1, git_reflog_entrycount(g_reflog)); entry = git_reflog_entry_byindex(g_reflog, entrycount - 2); - cl_assert(git_oid_streq(&entry->oid_old, GIT_OID_HEX_ZERO) == 0); + cl_assert(git_oid_streq(&entry->oid_old, GIT_OID_SHA1_HEXZERO) == 0); } void test_refs_reflog_drop__can_drop_all_the_entries(void) diff --git a/tests/libgit2/refs/reflog/messages.c b/tests/libgit2/refs/reflog/messages.c index ed183d2f2..647c00d0d 100644 --- a/tests/libgit2/refs/reflog/messages.c +++ b/tests/libgit2/refs/reflog/messages.c @@ -87,7 +87,7 @@ void test_refs_reflog_messages__detaching_writes_reflog(void) const char *msg; msg = "checkout: moving from master to e90810b8df3e80c413d903f631643c716887138d"; - git_oid_fromstr(&id, "e90810b8df3e80c413d903f631643c716887138d"); + git_oid__fromstr(&id, "e90810b8df3e80c413d903f631643c716887138d", GIT_OID_SHA1); cl_git_pass(git_repository_set_head_detached(g_repo, &id)); cl_reflog_check_entry(g_repo, GIT_HEAD_FILE, 0, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", @@ -109,7 +109,7 @@ void test_refs_reflog_messages__orphan_branch_does_not_count(void) /* Have something known */ msg = "checkout: moving from master to e90810b8df3e80c413d903f631643c716887138d"; - git_oid_fromstr(&id, "e90810b8df3e80c413d903f631643c716887138d"); + git_oid__fromstr(&id, "e90810b8df3e80c413d903f631643c716887138d", GIT_OID_SHA1); cl_git_pass(git_repository_set_head_detached(g_repo, &id)); cl_reflog_check_entry(g_repo, GIT_HEAD_FILE, 0, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", @@ -264,7 +264,7 @@ void test_refs_reflog_messages__creating_a_direct_reference(void) cl_assert_equal_sz(1, git_reflog_entrycount(reflog)); entry = git_reflog_entry_byindex(reflog, 0); - cl_assert(git_oid_streq(&entry->oid_old, GIT_OID_HEX_ZERO) == 0); + cl_assert(git_oid_streq(&entry->oid_old, GIT_OID_SHA1_HEXZERO) == 0); cl_assert_equal_oid(&id, &entry->oid_cur); cl_assert_equal_s(message, entry->msg); @@ -280,7 +280,7 @@ void test_refs_reflog_messages__newline_gets_replaced(void) git_oid oid; cl_git_pass(git_signature_now(&signature, "me", "foo@example.com")); - cl_git_pass(git_oid_fromstr(&oid, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750")); + cl_git_pass(git_oid__fromstr(&oid, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", GIT_OID_SHA1)); cl_git_pass(git_reflog_read(&reflog, g_repo, "HEAD")); cl_assert_equal_sz(7, git_reflog_entrycount(reflog)); @@ -352,7 +352,7 @@ void test_refs_reflog_messages__creating_branches_default_messages(void) cl_git_pass(git_str_printf(&buf, "branch: Created from %s", git_oid_tostr_s(git_commit_id(target)))); cl_reflog_check_entry(g_repo, "refs/heads/" NEW_BRANCH_NAME, 0, - GIT_OID_HEX_ZERO, + GIT_OID_SHA1_HEXZERO, git_oid_tostr_s(git_commit_id(target)), g_email, git_str_cstr(&buf)); @@ -362,7 +362,7 @@ void test_refs_reflog_messages__creating_branches_default_messages(void) cl_git_pass(git_branch_create_from_annotated(&branch2, g_repo, NEW_BRANCH_NAME, annotated, true)); cl_reflog_check_entry(g_repo, "refs/heads/" NEW_BRANCH_NAME, 0, - GIT_OID_HEX_ZERO, + GIT_OID_SHA1_HEXZERO, git_oid_tostr_s(git_commit_id(target)), g_email, "branch: Created from e90810b8df3"); diff --git a/tests/libgit2/refs/reflog/reflog.c b/tests/libgit2/refs/reflog/reflog.c index 32ce7ffb7..774ec6c93 100644 --- a/tests/libgit2/refs/reflog/reflog.c +++ b/tests/libgit2/refs/reflog/reflog.c @@ -52,7 +52,7 @@ static void assert_appends(const git_signature *committer, const git_oid *oid) /* The first one was the creation of the branch */ entry = git_reflog_entry_byindex(reflog, 2); - cl_assert(git_oid_streq(&entry->oid_old, GIT_OID_HEX_ZERO) == 0); + cl_assert(git_oid_streq(&entry->oid_old, GIT_OID_SHA1_HEXZERO) == 0); entry = git_reflog_entry_byindex(reflog, 1); assert_signature(committer, entry->committer); @@ -80,7 +80,7 @@ void test_refs_reflog_reflog__append_then_read(void) git_reflog *reflog; /* Create a new branch pointing at the HEAD */ - git_oid_fromstr(&oid, current_master_tip); + git_oid__fromstr(&oid, current_master_tip, GIT_OID_SHA1); cl_git_pass(git_reference_create(&ref, g_repo, new_ref, &oid, 0, NULL)); git_reference_free(ref); @@ -147,7 +147,7 @@ void test_refs_reflog_reflog__removes_empty_reflog_dir(void) git_oid id; /* Create a new branch pointing at the HEAD */ - git_oid_fromstr(&id, current_master_tip); + git_oid__fromstr(&id, current_master_tip, GIT_OID_SHA1); cl_git_pass(git_reference_create(&ref, g_repo, "refs/heads/new-dir/new-head", &id, 0, NULL)); git_str_joinpath(&log_path, git_repository_path(g_repo), GIT_REFLOG_DIR); @@ -159,7 +159,7 @@ void test_refs_reflog_reflog__removes_empty_reflog_dir(void) git_reference_free(ref); /* new ref creation should succeed since new-dir is empty */ - git_oid_fromstr(&id, current_master_tip); + git_oid__fromstr(&id, current_master_tip, GIT_OID_SHA1); cl_git_pass(git_reference_create(&ref, g_repo, "refs/heads/new-dir", &id, 0, NULL)); git_reference_free(ref); @@ -173,7 +173,7 @@ void test_refs_reflog_reflog__fails_gracefully_on_nonempty_reflog_dir(void) git_oid id; /* Create a new branch pointing at the HEAD */ - git_oid_fromstr(&id, current_master_tip); + git_oid__fromstr(&id, current_master_tip, GIT_OID_SHA1); cl_git_pass(git_reference_create(&ref, g_repo, "refs/heads/new-dir/new-head", &id, 0, NULL)); git_reference_free(ref); @@ -186,7 +186,7 @@ void test_refs_reflog_reflog__fails_gracefully_on_nonempty_reflog_dir(void) cl_must_pass(p_unlink("testrepo.git/refs/heads/new-dir/new-head")); /* new ref creation should fail since new-dir contains reflogs still */ - git_oid_fromstr(&id, current_master_tip); + git_oid__fromstr(&id, current_master_tip, GIT_OID_SHA1); cl_git_fail_with(GIT_EDIRECTORY, git_reference_create(&ref, g_repo, "refs/heads/new-dir", &id, 0, NULL)); git_reference_free(ref); @@ -235,7 +235,7 @@ void test_refs_reflog_reflog__reading_a_reflog_with_invalid_format_succeeds(void char *star; /* Create a new branch. */ - cl_git_pass(git_oid_fromstr(&id, current_master_tip)); + cl_git_pass(git_oid__fromstr(&id, current_master_tip, GIT_OID_SHA1)); cl_git_pass(git_reference_create(&ref, g_repo, refname, &id, 1, refmessage)); /* @@ -298,7 +298,7 @@ void test_refs_reflog_reflog__write_only_std_locations(void) git_reference *ref; git_oid id; - git_oid_fromstr(&id, current_master_tip); + git_oid__fromstr(&id, current_master_tip, GIT_OID_SHA1); cl_git_pass(git_reference_create(&ref, g_repo, "refs/heads/foo", &id, 1, NULL)); git_reference_free(ref); @@ -318,7 +318,7 @@ void test_refs_reflog_reflog__write_when_explicitly_active(void) git_reference *ref; git_oid id; - git_oid_fromstr(&id, current_master_tip); + git_oid__fromstr(&id, current_master_tip, GIT_OID_SHA1); git_reference_ensure_log(g_repo, "refs/tags/foo"); cl_git_pass(git_reference_create(&ref, g_repo, "refs/tags/foo", &id, 1, NULL)); @@ -338,7 +338,7 @@ void test_refs_reflog_reflog__append_to_HEAD_when_changing_current_branch(void) git_reflog_free(log); /* Move it back */ - git_oid_fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"); + git_oid__fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644", GIT_OID_SHA1); cl_git_pass(git_reference_create(&ref, g_repo, "refs/heads/master", &id, 1, NULL)); git_reference_free(ref); @@ -390,7 +390,7 @@ static void assert_no_reflog_update(void) git_reflog_free(log); /* Move it back */ - git_oid_fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"); + git_oid__fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644", GIT_OID_SHA1); cl_git_pass(git_reference_create(&ref, g_repo, "refs/heads/master", &id, 1, NULL)); git_reference_free(ref); @@ -431,7 +431,7 @@ void test_refs_reflog_reflog__logallrefupdates_bare_set_always(void) cl_git_pass(git_config_set_string(config, "core.logallrefupdates", "always")); git_config_free(config); - git_oid_fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"); + git_oid__fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644", GIT_OID_SHA1); cl_git_pass(git_reference_create(&ref, g_repo, "refs/bork", &id, 1, "message")); cl_git_pass(git_reflog_read(&log, g_repo, "refs/bork")); diff --git a/tests/libgit2/refs/reflog/reflog_helpers.c b/tests/libgit2/refs/reflog/reflog_helpers.c index 2ea41ee06..6a7e706d6 100644 --- a/tests/libgit2/refs/reflog/reflog_helpers.c +++ b/tests/libgit2/refs/reflog/reflog_helpers.c @@ -6,12 +6,12 @@ int reflog_entry_tostr(git_str *out, const git_reflog_entry *entry) { - char old_oid[GIT_OID_HEXSZ], new_oid[GIT_OID_HEXSZ]; + char old_oid[GIT_OID_SHA1_HEXSIZE], new_oid[GIT_OID_SHA1_HEXSIZE]; assert(out && entry); - git_oid_tostr((char *)&old_oid, GIT_OID_HEXSZ, git_reflog_entry_id_old(entry)); - git_oid_tostr((char *)&new_oid, GIT_OID_HEXSZ, git_reflog_entry_id_new(entry)); + git_oid_tostr((char *)&old_oid, GIT_OID_SHA1_HEXSIZE, git_reflog_entry_id_old(entry)); + git_oid_tostr((char *)&new_oid, GIT_OID_SHA1_HEXSIZE, git_reflog_entry_id_new(entry)); return git_str_printf(out, "%s %s %s %s", old_oid, new_oid, "somesig", git_reflog_entry_message(entry)); } @@ -46,17 +46,17 @@ void cl_reflog_check_entry_(git_repository *repo, const char *reflog, size_t idx git_object *obj = NULL; if (git_revparse_single(&obj, repo, old_spec) == GIT_OK) { if (git_oid_cmp(git_object_id(obj), git_reflog_entry_id_old(entry)) != 0) { - git_oid__writebuf(&result, "\tOld OID: \"", git_object_id(obj)); - git_oid__writebuf(&result, "\" != \"", git_reflog_entry_id_old(entry)); + git_object__write_oid_header(&result, "\tOld OID: \"", git_object_id(obj)); + git_object__write_oid_header(&result, "\" != \"", git_reflog_entry_id_old(entry)); git_str_puts(&result, "\"\n"); } git_object_free(obj); } else { git_oid *oid = git__calloc(1, sizeof(*oid)); - git_oid_fromstr(oid, old_spec); + git_oid__fromstr(oid, old_spec, GIT_OID_SHA1); if (git_oid_cmp(oid, git_reflog_entry_id_old(entry)) != 0) { - git_oid__writebuf(&result, "\tOld OID: \"", oid); - git_oid__writebuf(&result, "\" != \"", git_reflog_entry_id_old(entry)); + git_object__write_oid_header(&result, "\tOld OID: \"", oid); + git_object__write_oid_header(&result, "\" != \"", git_reflog_entry_id_old(entry)); git_str_puts(&result, "\"\n"); } git__free(oid); @@ -66,17 +66,17 @@ void cl_reflog_check_entry_(git_repository *repo, const char *reflog, size_t idx git_object *obj = NULL; if (git_revparse_single(&obj, repo, new_spec) == GIT_OK) { if (git_oid_cmp(git_object_id(obj), git_reflog_entry_id_new(entry)) != 0) { - git_oid__writebuf(&result, "\tNew OID: \"", git_object_id(obj)); - git_oid__writebuf(&result, "\" != \"", git_reflog_entry_id_new(entry)); + git_object__write_oid_header(&result, "\tNew OID: \"", git_object_id(obj)); + git_object__write_oid_header(&result, "\" != \"", git_reflog_entry_id_new(entry)); git_str_puts(&result, "\"\n"); } git_object_free(obj); } else { git_oid *oid = git__calloc(1, sizeof(*oid)); - git_oid_fromstr(oid, new_spec); + git_oid__fromstr(oid, new_spec, GIT_OID_SHA1); if (git_oid_cmp(oid, git_reflog_entry_id_new(entry)) != 0) { - git_oid__writebuf(&result, "\tNew OID: \"", oid); - git_oid__writebuf(&result, "\" != \"", git_reflog_entry_id_new(entry)); + git_object__write_oid_header(&result, "\tNew OID: \"", oid); + git_object__write_oid_header(&result, "\" != \"", git_reflog_entry_id_new(entry)); git_str_puts(&result, "\"\n"); } git__free(oid); diff --git a/tests/libgit2/refs/revparse.c b/tests/libgit2/refs/revparse.c index 56af3c939..d2f464840 100644 --- a/tests/libgit2/refs/revparse.c +++ b/tests/libgit2/refs/revparse.c @@ -304,6 +304,9 @@ void test_refs_revparse__ordinal(void) test_object("@{0}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"); test_object("@{1}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"); + test_object("HEAD@{0}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"); + test_object("HEAD@{4}", "5b5b025afb0b4c913b4c338a42934a3863bf3644"); + test_object("master@{0}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"); test_object("master@{1}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"); test_object("heads/master@{1}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"); @@ -652,7 +655,7 @@ void test_refs_revparse__try_to_retrieve_branch_before_described_tag(void) git_repository *repo; git_reference *branch; git_object *target; - char sha[GIT_OID_HEXSZ + 1]; + char sha[GIT_OID_SHA1_HEXSIZE + 1]; repo = cl_git_sandbox_init("testrepo.git"); @@ -661,7 +664,7 @@ void test_refs_revparse__try_to_retrieve_branch_before_described_tag(void) cl_git_pass(git_revparse_single(&target, repo, "HEAD~3")); cl_git_pass(git_branch_create(&branch, repo, "blah-7-gc47800c", (git_commit *)target, 0)); - git_oid_tostr(sha, GIT_OID_HEXSZ + 1, git_object_id(target)); + git_oid_tostr(sha, GIT_OID_SHA1_HEXSIZE + 1, git_object_id(target)); test_object_inrepo("blah-7-gc47800c", sha, repo); @@ -690,7 +693,7 @@ void test_refs_revparse__try_to_retrieve_sha_before_branch(void) git_repository *repo; git_reference *branch; git_object *target; - char sha[GIT_OID_HEXSZ + 1]; + char sha[GIT_OID_SHA1_HEXSIZE + 1]; repo = cl_git_sandbox_init("testrepo.git"); @@ -699,7 +702,7 @@ void test_refs_revparse__try_to_retrieve_sha_before_branch(void) cl_git_pass(git_revparse_single(&target, repo, "HEAD~3")); cl_git_pass(git_branch_create(&branch, repo, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", (git_commit *)target, 0)); - git_oid_tostr(sha, GIT_OID_HEXSZ + 1, git_object_id(target)); + git_oid_tostr(sha, GIT_OID_SHA1_HEXSIZE + 1, git_object_id(target)); test_object_inrepo("a65fedf39aefe402d3bb6e24df4d4f5fe4547750", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", repo); test_object_inrepo("heads/a65fedf39aefe402d3bb6e24df4d4f5fe4547750", sha, repo); @@ -726,7 +729,7 @@ void test_refs_revparse__try_to_retrieve_branch_before_abbrev_sha(void) git_repository *repo; git_reference *branch; git_object *target; - char sha[GIT_OID_HEXSZ + 1]; + char sha[GIT_OID_SHA1_HEXSIZE + 1]; repo = cl_git_sandbox_init("testrepo.git"); @@ -735,7 +738,7 @@ void test_refs_revparse__try_to_retrieve_branch_before_abbrev_sha(void) cl_git_pass(git_revparse_single(&target, repo, "HEAD~3")); cl_git_pass(git_branch_create(&branch, repo, "c47800", (git_commit *)target, 0)); - git_oid_tostr(sha, GIT_OID_HEXSZ + 1, git_object_id(target)); + git_oid_tostr(sha, GIT_OID_SHA1_HEXSIZE + 1, git_object_id(target)); test_object_inrepo("c47800", sha, repo); diff --git a/tests/libgit2/refs/transactions.c b/tests/libgit2/refs/transactions.c index 50c102ad0..98ae6f73a 100644 --- a/tests/libgit2/refs/transactions.c +++ b/tests/libgit2/refs/transactions.c @@ -21,7 +21,7 @@ void test_refs_transactions__single_ref_oid(void) git_reference *ref; git_oid id; - git_oid_fromstr(&id, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"); + git_oid__fromstr(&id, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", GIT_OID_SHA1); cl_git_pass(git_transaction_lock_ref(g_tx, "refs/heads/master")); cl_git_pass(git_transaction_set_target(g_tx, "refs/heads/master", &id, NULL, NULL)); @@ -52,7 +52,7 @@ void test_refs_transactions__single_ref_mix_types(void) git_reference *ref; git_oid id; - git_oid_fromstr(&id, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"); + git_oid__fromstr(&id, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", GIT_OID_SHA1); cl_git_pass(git_transaction_lock_ref(g_tx, "refs/heads/master")); cl_git_pass(git_transaction_lock_ref(g_tx, "HEAD")); @@ -90,7 +90,7 @@ void test_refs_transactions__single_create(void) cl_git_pass(git_transaction_lock_ref(g_tx, name)); - git_oid_fromstr(&id, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"); + git_oid__fromstr(&id, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", GIT_OID_SHA1); cl_git_pass(git_transaction_set_target(g_tx, name, &id, NULL, NULL)); cl_git_pass(git_transaction_commit(g_tx)); @@ -104,7 +104,7 @@ void test_refs_transactions__unlocked_set(void) git_oid id; cl_git_pass(git_transaction_lock_ref(g_tx, "refs/heads/master")); - git_oid_fromstr(&id, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"); + git_oid__fromstr(&id, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", GIT_OID_SHA1); cl_git_fail_with(GIT_ENOTFOUND, git_transaction_set_target(g_tx, "refs/heads/foo", &id, NULL, NULL)); cl_git_pass(git_transaction_commit(g_tx)); } @@ -122,7 +122,7 @@ void test_refs_transactions__error_on_locking_locked_ref(void) cl_git_pass(git_transaction_lock_ref(g_tx_with_lock, "refs/heads/master")); /* lock reference for set_target */ - cl_git_pass(git_oid_fromstr(&id, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750")); + cl_git_pass(git_oid__fromstr(&id, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", GIT_OID_SHA1)); cl_git_fail_with(GIT_ELOCKED, git_transaction_lock_ref(g_tx, "refs/heads/master")); cl_git_fail_with(GIT_ENOTFOUND, git_transaction_set_target(g_tx, "refs/heads/master", &id, NULL, NULL)); diff --git a/tests/libgit2/remote/httpproxy.c b/tests/libgit2/remote/httpproxy.c index f62a2545b..60fc67dec 100644 --- a/tests/libgit2/remote/httpproxy.c +++ b/tests/libgit2/remote/httpproxy.c @@ -6,7 +6,6 @@ static git_repository *repo; static git_net_url url = GIT_NET_URL_INIT; -static int orig_proxies_need_reset = 0; static char *orig_http_proxy = NULL; static char *orig_https_proxy = NULL; static char *orig_no_proxy = NULL; @@ -21,20 +20,25 @@ void test_remote_httpproxy__initialize(void) git_remote_free(remote); - orig_proxies_need_reset = 0; + /* Clear everything for a fresh start */ + orig_http_proxy = cl_getenv("HTTP_PROXY"); + orig_https_proxy = cl_getenv("HTTPS_PROXY"); + orig_no_proxy = cl_getenv("NO_PROXY"); + + cl_setenv("HTTP_PROXY", NULL); + cl_setenv("HTTPS_PROXY", NULL); + cl_setenv("NO_PROXY", NULL); } void test_remote_httpproxy__cleanup(void) { - if (orig_proxies_need_reset) { - cl_setenv("HTTP_PROXY", orig_http_proxy); - cl_setenv("HTTPS_PROXY", orig_https_proxy); - cl_setenv("NO_PROXY", orig_no_proxy); + cl_setenv("HTTP_PROXY", orig_http_proxy); + cl_setenv("HTTPS_PROXY", orig_https_proxy); + cl_setenv("NO_PROXY", orig_no_proxy); - git__free(orig_http_proxy); - git__free(orig_https_proxy); - git__free(orig_no_proxy); - } + git__free(orig_http_proxy); + git__free(orig_https_proxy); + git__free(orig_no_proxy); git_net_url_dispose(&url); cl_git_sandbox_cleanup(); @@ -132,7 +136,7 @@ static void assert_global_config_match(const char *config, const char *expected) void test_remote_httpproxy__config_overrides_detached_remote(void) { - cl_fake_home(); + cl_fake_globalconfig(NULL); assert_global_config_match(NULL, NULL); assert_global_config_match("http.proxy", "http://localhost:1/"); @@ -141,22 +145,10 @@ void test_remote_httpproxy__config_overrides_detached_remote(void) assert_global_config_match("http.https://github.com/libgit2.proxy", "http://localhost:4/"); assert_global_config_match("http.https://github.com/libgit2/.proxy", "http://localhost:5/"); assert_global_config_match("http.https://github.com/libgit2/libgit2.proxy", "http://localhost:6/"); - - cl_git_pass(git_futils_rmdir_r("home", NULL, GIT_RMDIR_REMOVE_FILES)); } void test_remote_httpproxy__env(void) { - orig_http_proxy = cl_getenv("HTTP_PROXY"); - orig_https_proxy = cl_getenv("HTTPS_PROXY"); - orig_no_proxy = cl_getenv("NO_PROXY"); - orig_proxies_need_reset = 1; - - /* Clear everything for a fresh start */ - cl_setenv("HTTP_PROXY", NULL); - cl_setenv("HTTPS_PROXY", NULL); - cl_setenv("NO_PROXY", NULL); - /* HTTP proxy is ignored for HTTPS */ cl_setenv("HTTP_PROXY", "http://localhost:9/"); assert_proxy_is(NULL); diff --git a/tests/libgit2/repo/env.c b/tests/libgit2/repo/env.c index e3e522480..790ffd40f 100644 --- a/tests/libgit2/repo/env.c +++ b/tests/libgit2/repo/env.c @@ -95,9 +95,9 @@ static void env_check_objects_(bool a, bool t, bool p, const char *file, const c git_repository *repo; git_oid oid_a, oid_t, oid_p; git_object *object; - cl_git_pass(git_oid_fromstr(&oid_a, "45141a79a77842c59a63229403220a4e4be74e3d")); - cl_git_pass(git_oid_fromstr(&oid_t, "1385f264afb75a56a5bec74243be9b367ba4ca08")); - cl_git_pass(git_oid_fromstr(&oid_p, "0df1a5865c8abfc09f1f2182e6a31be550e99f07")); + cl_git_pass(git_oid__fromstr(&oid_a, "45141a79a77842c59a63229403220a4e4be74e3d", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&oid_t, "1385f264afb75a56a5bec74243be9b367ba4ca08", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&oid_p, "0df1a5865c8abfc09f1f2182e6a31be550e99f07", GIT_OID_SHA1)); cl_git_expect(git_repository_open_ext(&repo, "attr", GIT_REPOSITORY_OPEN_FROM_ENV, NULL), 0, file, func, line); if (a) { diff --git a/tests/libgit2/repo/extensions.c b/tests/libgit2/repo/extensions.c index e7772acd5..105cdae12 100644 --- a/tests/libgit2/repo/extensions.c +++ b/tests/libgit2/repo/extensions.c @@ -3,7 +3,7 @@ #include "sysdir.h" #include -git_repository *repo; +static git_repository *repo; void test_repo_extensions__initialize(void) { diff --git a/tests/libgit2/repo/hashfile.c b/tests/libgit2/repo/hashfile.c index e23bb77f9..f053cb950 100644 --- a/tests/libgit2/repo/hashfile.c +++ b/tests/libgit2/repo/hashfile.c @@ -1,4 +1,5 @@ #include "clar_libgit2.h" +#include "odb.h" static git_repository *_repo; @@ -20,19 +21,19 @@ void test_repo_hashfile__simple(void) git_str full = GIT_STR_INIT; /* hash with repo relative path */ - cl_git_pass(git_odb_hashfile(&a, "status/current_file", GIT_OBJECT_BLOB)); + cl_git_pass(git_odb__hashfile(&a, "status/current_file", GIT_OBJECT_BLOB, GIT_OID_SHA1)); cl_git_pass(git_repository_hashfile(&b, _repo, "current_file", GIT_OBJECT_BLOB, NULL)); cl_assert_equal_oid(&a, &b); cl_git_pass(git_str_joinpath(&full, git_repository_workdir(_repo), "current_file")); /* hash with full path */ - cl_git_pass(git_odb_hashfile(&a, full.ptr, GIT_OBJECT_BLOB)); + cl_git_pass(git_odb__hashfile(&a, full.ptr, GIT_OBJECT_BLOB, GIT_OID_SHA1)); cl_git_pass(git_repository_hashfile(&b, _repo, full.ptr, GIT_OBJECT_BLOB, NULL)); cl_assert_equal_oid(&a, &b); /* hash with invalid type */ - cl_git_fail(git_odb_hashfile(&a, full.ptr, GIT_OBJECT_ANY)); + cl_git_fail(git_odb__hashfile(&a, full.ptr, GIT_OBJECT_ANY, GIT_OID_SHA1)); cl_git_fail(git_repository_hashfile(&b, _repo, full.ptr, GIT_OBJECT_OFS_DELTA, NULL)); git_str_dispose(&full); @@ -59,64 +60,64 @@ void test_repo_hashfile__filtered_in_workdir(void) cl_git_mkfile("status/testfile.bin", "other\r\nstuff\r\n"); /* not equal hashes because of filtering */ - cl_git_pass(git_odb_hashfile(&a, "status/testfile.txt", GIT_OBJECT_BLOB)); + cl_git_pass(git_odb__hashfile(&a, "status/testfile.txt", GIT_OBJECT_BLOB, GIT_OID_SHA1)); cl_git_pass(git_repository_hashfile(&b, _repo, "testfile.txt", GIT_OBJECT_BLOB, NULL)); cl_assert(git_oid_cmp(&a, &b)); /* not equal hashes because of filtering when specified by absolute path */ - cl_git_pass(git_odb_hashfile(&a, "status/testfile.txt", GIT_OBJECT_BLOB)); + cl_git_pass(git_odb__hashfile(&a, "status/testfile.txt", GIT_OBJECT_BLOB, GIT_OID_SHA1)); cl_git_pass(git_repository_hashfile(&b, _repo, txt.ptr, GIT_OBJECT_BLOB, NULL)); cl_assert(git_oid_cmp(&a, &b)); /* equal hashes because filter is binary */ - cl_git_pass(git_odb_hashfile(&a, "status/testfile.bin", GIT_OBJECT_BLOB)); + cl_git_pass(git_odb__hashfile(&a, "status/testfile.bin", GIT_OBJECT_BLOB, GIT_OID_SHA1)); cl_git_pass(git_repository_hashfile(&b, _repo, "testfile.bin", GIT_OBJECT_BLOB, NULL)); cl_assert_equal_oid(&a, &b); /* equal hashes because filter is binary when specified by absolute path */ - cl_git_pass(git_odb_hashfile(&a, "status/testfile.bin", GIT_OBJECT_BLOB)); + cl_git_pass(git_odb__hashfile(&a, "status/testfile.bin", GIT_OBJECT_BLOB, GIT_OID_SHA1)); cl_git_pass(git_repository_hashfile(&b, _repo, bin.ptr, GIT_OBJECT_BLOB, NULL)); cl_assert_equal_oid(&a, &b); /* equal hashes when 'as_file' points to binary filtering */ - cl_git_pass(git_odb_hashfile(&a, "status/testfile.txt", GIT_OBJECT_BLOB)); + cl_git_pass(git_odb__hashfile(&a, "status/testfile.txt", GIT_OBJECT_BLOB, GIT_OID_SHA1)); cl_git_pass(git_repository_hashfile(&b, _repo, "testfile.txt", GIT_OBJECT_BLOB, "foo.bin")); cl_assert_equal_oid(&a, &b); /* equal hashes when 'as_file' points to binary filtering (absolute path) */ - cl_git_pass(git_odb_hashfile(&a, "status/testfile.txt", GIT_OBJECT_BLOB)); + cl_git_pass(git_odb__hashfile(&a, "status/testfile.txt", GIT_OBJECT_BLOB, GIT_OID_SHA1)); cl_git_pass(git_repository_hashfile(&b, _repo, txt.ptr, GIT_OBJECT_BLOB, "foo.bin")); cl_assert_equal_oid(&a, &b); /* not equal hashes when 'as_file' points to text filtering */ - cl_git_pass(git_odb_hashfile(&a, "status/testfile.bin", GIT_OBJECT_BLOB)); + cl_git_pass(git_odb__hashfile(&a, "status/testfile.bin", GIT_OBJECT_BLOB, GIT_OID_SHA1)); cl_git_pass(git_repository_hashfile(&b, _repo, "testfile.bin", GIT_OBJECT_BLOB, "foo.txt")); cl_assert(git_oid_cmp(&a, &b)); /* not equal hashes when 'as_file' points to text filtering */ - cl_git_pass(git_odb_hashfile(&a, "status/testfile.bin", GIT_OBJECT_BLOB)); + cl_git_pass(git_odb__hashfile(&a, "status/testfile.bin", GIT_OBJECT_BLOB, GIT_OID_SHA1)); cl_git_pass(git_repository_hashfile(&b, _repo, bin.ptr, GIT_OBJECT_BLOB, "foo.txt")); cl_assert(git_oid_cmp(&a, &b)); /* equal hashes when 'as_file' is empty and turns off filtering */ - cl_git_pass(git_odb_hashfile(&a, "status/testfile.txt", GIT_OBJECT_BLOB)); + cl_git_pass(git_odb__hashfile(&a, "status/testfile.txt", GIT_OBJECT_BLOB, GIT_OID_SHA1)); cl_git_pass(git_repository_hashfile(&b, _repo, "testfile.txt", GIT_OBJECT_BLOB, "")); cl_assert_equal_oid(&a, &b); - cl_git_pass(git_odb_hashfile(&a, "status/testfile.bin", GIT_OBJECT_BLOB)); + cl_git_pass(git_odb__hashfile(&a, "status/testfile.bin", GIT_OBJECT_BLOB, GIT_OID_SHA1)); cl_git_pass(git_repository_hashfile(&b, _repo, "testfile.bin", GIT_OBJECT_BLOB, "")); cl_assert_equal_oid(&a, &b); - cl_git_pass(git_odb_hashfile(&a, "status/testfile.txt", GIT_OBJECT_BLOB)); + cl_git_pass(git_odb__hashfile(&a, "status/testfile.txt", GIT_OBJECT_BLOB, GIT_OID_SHA1)); cl_git_pass(git_repository_hashfile(&b, _repo, txt.ptr, GIT_OBJECT_BLOB, "")); cl_assert_equal_oid(&a, &b); - cl_git_pass(git_odb_hashfile(&a, "status/testfile.bin", GIT_OBJECT_BLOB)); + cl_git_pass(git_odb__hashfile(&a, "status/testfile.bin", GIT_OBJECT_BLOB, GIT_OID_SHA1)); cl_git_pass(git_repository_hashfile(&b, _repo, bin.ptr, GIT_OBJECT_BLOB, "")); cl_assert_equal_oid(&a, &b); /* some hash type failures */ - cl_git_fail(git_odb_hashfile(&a, "status/testfile.txt", 0)); + cl_git_fail(git_odb__hashfile(&a, "status/testfile.txt", 0, GIT_OID_SHA1)); cl_git_fail(git_repository_hashfile(&b, _repo, "testfile.txt", GIT_OBJECT_ANY, NULL)); git_str_dispose(&txt); @@ -144,12 +145,12 @@ void test_repo_hashfile__filtered_outside_workdir(void) cl_git_mkfile("absolute/testfile.bin", "other\r\nstuff\r\n"); /* not equal hashes because of filtering */ - cl_git_pass(git_odb_hashfile(&a, "absolute/testfile.txt", GIT_OBJECT_BLOB)); + cl_git_pass(git_odb__hashfile(&a, "absolute/testfile.txt", GIT_OBJECT_BLOB, GIT_OID_SHA1)); cl_git_pass(git_repository_hashfile(&b, _repo, txt.ptr, GIT_OBJECT_BLOB, "testfile.txt")); cl_assert(git_oid_cmp(&a, &b)); /* equal hashes because filter is binary */ - cl_git_pass(git_odb_hashfile(&a, "absolute/testfile.bin", GIT_OBJECT_BLOB)); + cl_git_pass(git_odb__hashfile(&a, "absolute/testfile.bin", GIT_OBJECT_BLOB, GIT_OID_SHA1)); cl_git_pass(git_repository_hashfile(&b, _repo, bin.ptr, GIT_OBJECT_BLOB, "testfile.bin")); cl_assert_equal_oid(&a, &b); @@ -157,11 +158,11 @@ void test_repo_hashfile__filtered_outside_workdir(void) * equal hashes because no filtering occurs for absolute paths outside the working * directory unless as_path is specified */ - cl_git_pass(git_odb_hashfile(&a, "absolute/testfile.txt", GIT_OBJECT_BLOB)); + cl_git_pass(git_odb__hashfile(&a, "absolute/testfile.txt", GIT_OBJECT_BLOB, GIT_OID_SHA1)); cl_git_pass(git_repository_hashfile(&b, _repo, txt.ptr, GIT_OBJECT_BLOB, NULL)); cl_assert_equal_oid(&a, &b); - cl_git_pass(git_odb_hashfile(&a, "absolute/testfile.bin", GIT_OBJECT_BLOB)); + cl_git_pass(git_odb__hashfile(&a, "absolute/testfile.bin", GIT_OBJECT_BLOB, GIT_OID_SHA1)); cl_git_pass(git_repository_hashfile(&b, _repo, bin.ptr, GIT_OBJECT_BLOB, NULL)); cl_assert_equal_oid(&a, &b); diff --git a/tests/libgit2/repo/head.c b/tests/libgit2/repo/head.c index 822990555..c886c3f79 100644 --- a/tests/libgit2/repo/head.c +++ b/tests/libgit2/repo/head.c @@ -99,7 +99,7 @@ void test_repo_head__set_head_detached_Return_ENOTFOUND_when_the_object_doesnt_e { git_oid oid; - cl_git_pass(git_oid_fromstr(&oid, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef")); + cl_git_pass(git_oid__fromstr(&oid, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef", GIT_OID_SHA1)); cl_assert_equal_i(GIT_ENOTFOUND, git_repository_set_head_detached(repo, &oid)); } diff --git a/tests/libgit2/repo/init.c b/tests/libgit2/repo/init.c index 7cf6742ca..d78ec063c 100644 --- a/tests/libgit2/repo/init.c +++ b/tests/libgit2/repo/init.c @@ -142,30 +142,49 @@ void test_repo_init__reinit_bare_repo(void) cl_git_pass(git_repository_init(&g_repo, "reinit.git", 1)); } -void test_repo_init__reinit_too_recent_bare_repo(void) +void test_repo_init__reinit_nondefault_version(void) { git_config *config; + cl_set_cleanup(&cleanup_repository, "reinit.git"); + /* Initialize the repository */ cl_git_pass(git_repository_init(&g_repo, "reinit.git", 1)); git_repository_config(&config, g_repo); - /* - * Hack the config of the repository to make it look like it has - * been created by a recenter version of git/libgit2 - */ - cl_git_pass(git_config_set_int32(config, "core.repositoryformatversion", 42)); - + /* Set the config to a supported but not default version */ + cl_repo_set_string(g_repo, "core.repositoryformatversion", "1"); git_config_free(config); git_repository_free(g_repo); g_repo = NULL; /* Try to reinitialize the repository */ - cl_git_fail(git_repository_init(&g_repo, "reinit.git", 1)); + cl_git_pass(git_repository_init(&g_repo, "reinit.git", 1)); + cl_assert_equal_i(1, cl_repo_get_int(g_repo, "core.repositoryformatversion")); cl_fixture_cleanup("reinit.git"); } +void test_repo_init__reinit_unsupported_version(void) +{ + cl_set_cleanup(&cleanup_repository, "reinit.git"); + + /* Initialize the repository */ + cl_git_pass(git_repository_init(&g_repo, "reinit.git", 1)); + + /* + * Hack the config of the repository to make it look like it has + * been created by a too new and unsupported version of git/libgit2 + */ + cl_repo_set_string(g_repo, "core.repositoryformatversion", "42"); + git_repository_free(g_repo); + g_repo = NULL; + + /* Try and fail to reinitialize the repository */ + cl_git_fail(git_repository_init(&g_repo, "reinit.git", 1)); + cl_fixture_cleanup("reinit.git"); +} + void test_repo_init__additional_templates(void) { git_str path = GIT_STR_INIT; @@ -708,7 +727,7 @@ void test_repo_init__defaultbranch_config_empty(void) void test_repo_init__longpath(void) { #ifdef GIT_WIN32 - size_t padding = CONST_STRLEN("objects/pack/pack-.pack.lock") + GIT_OID_HEXSZ; + size_t padding = CONST_STRLEN("objects/pack/pack-.pack.lock") + GIT_OID_MAX_HEXSIZE; size_t max, i; git_str path = GIT_STR_INIT; git_repository *one = NULL, *two = NULL; diff --git a/tests/libgit2/repo/objectformat.c b/tests/libgit2/repo/objectformat.c new file mode 100644 index 000000000..d278e10c4 --- /dev/null +++ b/tests/libgit2/repo/objectformat.c @@ -0,0 +1,69 @@ +#include "clar_libgit2.h" +#include "futils.h" +#include "sysdir.h" +#include "repository.h" +#include + +static git_repository *repo; +static git_config *config; + +void test_repo_objectformat__initialize(void) +{ + repo = cl_git_sandbox_init("empty_bare.git"); + + cl_git_pass(git_repository_config(&config, repo)); + cl_git_pass(git_config_set_int32(config, "core.repositoryformatversion", 1)); +} + +void test_repo_objectformat__cleanup(void) +{ + git_config_free(config); + cl_git_sandbox_cleanup(); +} + +void test_repo_objectformat__unspecified(void) +{ + git_repository *other; + + cl_git_pass(git_repository_open(&other, "empty_bare.git")); + cl_assert_equal_i(GIT_OID_SHA1, git_repository_oid_type(other)); + git_repository_free(other); +} + +void test_repo_objectformat__sha1(void) +{ + git_repository *other; + + cl_git_pass(git_config_set_string(config, "extensions.objectformat", "sha1")); + + cl_git_pass(git_repository_open(&other, "empty_bare.git")); + cl_assert_equal_i(GIT_OID_SHA1, git_repository_oid_type(other)); + git_repository_free(other); +} + +void test_repo_objectformat__sha256(void) +{ +#ifndef GIT_EXPERIMENTAL_SHA256 + cl_skip(); +#else + git_repository *other; + + cl_git_pass(git_config_set_string(config, "extensions.objectformat", "sha256")); + + cl_git_pass(git_repository_open(&other, "empty_bare.git")); + cl_assert_equal_i(GIT_OID_SHA256, git_repository_oid_type(other)); + git_repository_free(other); +#endif +} + +void test_repo_objectformat__invalid(void) +{ + git_repository *other; + + cl_git_pass(git_config_set_string(config, "extensions.objectformat", "bogus")); + + cl_git_fail_with(GIT_EINVALID, git_repository_open(&other, "empty_bare.git")); + cl_assert_equal_s("unknown object format 'bogus'", git_error_last()->message); + git_repository_free(other); +} + diff --git a/tests/libgit2/repo/open.c b/tests/libgit2/repo/open.c index 634ba59d2..3d1a0620b 100644 --- a/tests/libgit2/repo/open.c +++ b/tests/libgit2/repo/open.c @@ -410,6 +410,7 @@ void test_repo_open__no_config(void) git_str_dispose(&path); cl_git_pass(git_repository_open(&repo, "empty_standard_repo")); + cl_assert(git_repository_oid_type(repo) == GIT_OID_SHA1); cl_git_pass(git_repository_config(&config, repo)); cl_git_pass(git_config_set_string(config, "test.set", "42")); @@ -433,11 +434,13 @@ void test_repo_open__force_bare(void) cl_git_pass(git_repository_open(&barerepo, "alternate")); cl_assert(!git_repository_is_bare(barerepo)); + cl_assert(git_repository_oid_type(barerepo) == GIT_OID_SHA1); git_repository_free(barerepo); cl_git_pass(git_repository_open_bare( &barerepo, "empty_standard_repo/.git")); cl_assert(git_repository_is_bare(barerepo)); + cl_assert(git_repository_oid_type(barerepo) == GIT_OID_SHA1); git_repository_free(barerepo); cl_git_fail(git_repository_open_bare(&barerepo, "alternate/.git")); @@ -487,7 +490,7 @@ void test_repo_open__validates_dir_ownership(void) /* When the system user owns the repo config, fail */ git_fs_path__set_owner(GIT_FS_PATH_OWNER_ADMINISTRATOR); - cl_git_fail(git_repository_open(&repo, "empty_standard_repo")); + cl_git_fail_with(GIT_EOWNER, git_repository_open(&repo, "empty_standard_repo")); #ifdef GIT_WIN32 /* When the user is an administrator, succeed on Windows. */ @@ -498,7 +501,7 @@ void test_repo_open__validates_dir_ownership(void) /* When an unknown user owns the repo config, fail */ git_fs_path__set_owner(GIT_FS_PATH_OWNER_OTHER); - cl_git_fail(git_repository_open(&repo, "empty_standard_repo")); + cl_git_fail_with(GIT_EOWNER, git_repository_open(&repo, "empty_standard_repo")); } void test_repo_open__validates_bare_repo_ownership(void) @@ -516,7 +519,7 @@ void test_repo_open__validates_bare_repo_ownership(void) /* When the system user owns the repo config, fail */ git_fs_path__set_owner(GIT_FS_PATH_OWNER_ADMINISTRATOR); - cl_git_fail(git_repository_open(&repo, "testrepo.git")); + cl_git_fail_with(GIT_EOWNER, git_repository_open(&repo, "testrepo.git")); #ifdef GIT_WIN32 /* When the user is an administrator, succeed on Windows. */ @@ -527,7 +530,7 @@ void test_repo_open__validates_bare_repo_ownership(void) /* When an unknown user owns the repo config, fail */ git_fs_path__set_owner(GIT_FS_PATH_OWNER_OTHER); - cl_git_fail(git_repository_open(&repo, "testrepo.git")); + cl_git_fail_with(GIT_EOWNER, git_repository_open(&repo, "testrepo.git")); } void test_repo_open__can_allowlist_dirs_with_problematic_ownership(void) @@ -543,7 +546,7 @@ void test_repo_open__can_allowlist_dirs_with_problematic_ownership(void) cl_git_pass(cl_rename("empty_standard_repo/.gitted", "empty_standard_repo/.git")); git_fs_path__set_owner(GIT_FS_PATH_OWNER_OTHER); - cl_git_fail(git_repository_open(&repo, "empty_standard_repo")); + cl_git_fail_with(GIT_EOWNER, git_repository_open(&repo, "empty_standard_repo")); /* Add safe.directory options to the global configuration */ git_str_joinpath(&config_path, clar_sandbox_path(), "__global_config"); @@ -575,6 +578,45 @@ void test_repo_open__can_allowlist_dirs_with_problematic_ownership(void) git_str_dispose(&config_data); } +void test_repo_open__can_wildcard_allowlist_with_problematic_ownership(void) +{ + git_repository *repo; + git_str config_path = GIT_STR_INIT, config_filename = GIT_STR_INIT; + + cl_git_pass(git_libgit2_opts(GIT_OPT_SET_OWNER_VALIDATION, 1)); + + cl_fixture_sandbox("empty_standard_repo"); + cl_git_pass(cl_rename( + "empty_standard_repo/.gitted", "empty_standard_repo/.git")); + + git_fs_path__set_owner(GIT_FS_PATH_OWNER_OTHER); + cl_git_fail_with( + GIT_EOWNER, git_repository_open(&repo, "empty_standard_repo")); + + /* Add safe.directory options to the global configuration */ + git_str_joinpath(&config_path, clar_sandbox_path(), "__global_config"); + cl_must_pass(p_mkdir(config_path.ptr, 0777)); + git_libgit2_opts( + GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, + config_path.ptr); + + git_str_joinpath(&config_filename, config_path.ptr, ".gitconfig"); + + cl_git_rewritefile(config_filename.ptr, "[foo]\n" + "\tbar = Foobar\n" + "\tbaz = Baz!\n" + "[safe]\n" + "\tdirectory = *\n" + "[bar]\n" + "\tfoo = barfoo\n"); + + cl_git_pass(git_repository_open(&repo, "empty_standard_repo")); + git_repository_free(repo); + + git_str_dispose(&config_path); + git_str_dispose(&config_filename); +} + void test_repo_open__can_allowlist_bare_gitdir(void) { git_repository *repo; @@ -587,7 +629,7 @@ void test_repo_open__can_allowlist_bare_gitdir(void) cl_fixture_sandbox("testrepo.git"); git_fs_path__set_owner(GIT_FS_PATH_OWNER_OTHER); - cl_git_fail(git_repository_open(&repo, "testrepo.git")); + cl_git_fail_with(GIT_EOWNER, git_repository_open(&repo, "testrepo.git")); /* Add safe.directory options to the global configuration */ git_str_joinpath(&config_path, clar_sandbox_path(), "__global_config"); @@ -619,6 +661,43 @@ void test_repo_open__can_allowlist_bare_gitdir(void) git_str_dispose(&config_data); } +void test_repo_open__can_wildcard_allowlist_bare_gitdir(void) +{ + git_repository *repo; + git_str config_path = GIT_STR_INIT, config_filename = GIT_STR_INIT; + + cl_git_pass(git_libgit2_opts(GIT_OPT_SET_OWNER_VALIDATION, 1)); + + cl_fixture_sandbox("testrepo.git"); + + git_fs_path__set_owner(GIT_FS_PATH_OWNER_OTHER); + cl_git_fail_with( + GIT_EOWNER, git_repository_open(&repo, "testrepo.git")); + + /* Add safe.directory options to the global configuration */ + git_str_joinpath(&config_path, clar_sandbox_path(), "__global_config"); + cl_must_pass(p_mkdir(config_path.ptr, 0777)); + git_libgit2_opts( + GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, + config_path.ptr); + + git_str_joinpath(&config_filename, config_path.ptr, ".gitconfig"); + + cl_git_rewritefile(config_filename.ptr, "[foo]\n" + "\tbar = Foobar\n" + "\tbaz = Baz!\n" + "[safe]\n" + "\tdirectory = *\n" + "[bar]\n" + "\tfoo = barfoo\n"); + + cl_git_pass(git_repository_open(&repo, "testrepo.git")); + git_repository_free(repo); + + git_str_dispose(&config_path); + git_str_dispose(&config_filename); +} + void test_repo_open__can_reset_safe_directory_list(void) { git_repository *repo; @@ -632,7 +711,7 @@ void test_repo_open__can_reset_safe_directory_list(void) cl_git_pass(cl_rename("empty_standard_repo/.gitted", "empty_standard_repo/.git")); git_fs_path__set_owner(GIT_FS_PATH_OWNER_OTHER); - cl_git_fail(git_repository_open(&repo, "empty_standard_repo")); + cl_git_fail_with(GIT_EOWNER, git_repository_open(&repo, "empty_standard_repo")); /* Add safe.directory options to the global configuration */ git_str_joinpath(&config_path, clar_sandbox_path(), "__global_config"); @@ -656,7 +735,7 @@ void test_repo_open__can_reset_safe_directory_list(void) clar_sandbox_path(), "empty_standard_repo"); cl_git_rewritefile(config_filename.ptr, config_data.ptr); - cl_git_fail(git_repository_open(&repo, "empty_standard_repo")); + cl_git_fail_with(GIT_EOWNER, git_repository_open(&repo, "empty_standard_repo")); /* The blank resets tmp and allows subsequent declarations to succeed */ diff --git a/tests/libgit2/repo/setters.c b/tests/libgit2/repo/setters.c index 9a965dec6..66ec7706c 100644 --- a/tests/libgit2/repo/setters.c +++ b/tests/libgit2/repo/setters.c @@ -1,6 +1,7 @@ #include "clar_libgit2.h" #include "git2/sys/repository.h" +#include "odb.h" #include "posix.h" #include "util.h" #include "path.h" @@ -90,7 +91,7 @@ void test_repo_setters__setting_a_new_odb_on_a_repo_which_already_loaded_one_pro { git_odb *new_odb; - cl_git_pass(git_odb_open(&new_odb, "./testrepo.git/objects")); + cl_git_pass(git_odb__open(&new_odb, "./testrepo.git/objects", NULL)); cl_assert(((git_refcount *)new_odb)->refcount.val == 1); git_repository_set_odb(repo, new_odb); diff --git a/tests/libgit2/reset/hard.c b/tests/libgit2/reset/hard.c index 9d177c021..0b6342cb2 100644 --- a/tests/libgit2/reset/hard.c +++ b/tests/libgit2/reset/hard.c @@ -122,9 +122,9 @@ static void unmerged_index_init(git_index *index, int entries) int write_theirs = 4; git_oid ancestor, ours, theirs; - git_oid_fromstr(&ancestor, "452e4244b5d083ddf0460acf1ecc74db9dcfa11a"); - git_oid_fromstr(&ours, "32504b727382542f9f089e24fddac5e78533e96c"); - git_oid_fromstr(&theirs, "061d42a44cacde5726057b67558821d95db96f19"); + git_oid__fromstr(&ancestor, "452e4244b5d083ddf0460acf1ecc74db9dcfa11a", GIT_OID_SHA1); + git_oid__fromstr(&ours, "32504b727382542f9f089e24fddac5e78533e96c", GIT_OID_SHA1); + git_oid__fromstr(&theirs, "061d42a44cacde5726057b67558821d95db96f19", GIT_OID_SHA1); cl_git_rewritefile("status/conflicting_file", "conflicting file\n"); diff --git a/tests/libgit2/reset/soft.c b/tests/libgit2/reset/soft.c index aca0834f2..128905021 100644 --- a/tests/libgit2/reset/soft.c +++ b/tests/libgit2/reset/soft.c @@ -53,11 +53,11 @@ void test_reset_soft__can_reset_the_detached_Head_to_the_specified_commit(void) void test_reset_soft__resetting_to_the_commit_pointed_at_by_the_Head_does_not_change_the_target_of_the_Head(void) { git_oid oid; - char raw_head_oid[GIT_OID_HEXSZ + 1]; + char raw_head_oid[GIT_OID_SHA1_HEXSIZE + 1]; cl_git_pass(git_reference_name_to_id(&oid, repo, "HEAD")); git_oid_fmt(raw_head_oid, &oid); - raw_head_oid[GIT_OID_HEXSZ] = '\0'; + raw_head_oid[GIT_OID_SHA1_HEXSIZE] = '\0'; cl_git_pass(git_revparse_single(&target, repo, raw_head_oid)); diff --git a/tests/libgit2/revert/bare.c b/tests/libgit2/revert/bare.c index 9261cfe86..db443024e 100644 --- a/tests/libgit2/revert/bare.c +++ b/tests/libgit2/revert/bare.c @@ -34,10 +34,10 @@ void test_revert_bare__automerge(void) { 0100644, "0f5bfcf58c558d865da6be0281d7795993646cee", 0, "file6.txt" }, }; - git_oid_fromstr(&head_oid, "72333f47d4e83616630ff3b0ffe4c0faebcc3c45"); + git_oid__fromstr(&head_oid, "72333f47d4e83616630ff3b0ffe4c0faebcc3c45", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&head_commit, repo, &head_oid)); - git_oid_fromstr(&revert_oid, "d1d403d22cbe24592d725f442835cf46fe60c8ac"); + git_oid__fromstr(&revert_oid, "d1d403d22cbe24592d725f442835cf46fe60c8ac", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&revert_commit, repo, &revert_oid)); cl_git_pass(git_revert_commit(&index, repo, revert_commit, head_commit, 0, NULL)); @@ -64,7 +64,7 @@ void test_revert_bare__conflicts(void) { 0100644, "0f5bfcf58c558d865da6be0281d7795993646cee", 0, "file6.txt" }, }; - git_oid_fromstr(&revert_oid, "72333f47d4e83616630ff3b0ffe4c0faebcc3c45"); + git_oid__fromstr(&revert_oid, "72333f47d4e83616630ff3b0ffe4c0faebcc3c45", GIT_OID_SHA1); cl_git_pass(git_repository_head(&head_ref, repo)); cl_git_pass(git_reference_peel((git_object **)&head_commit, head_ref, GIT_OBJECT_COMMIT)); @@ -91,10 +91,10 @@ void test_revert_bare__orphan(void) { 0100644, "296a6d3be1dff05c5d1f631d2459389fa7b619eb", 0, "file-mainline.txt" }, }; - git_oid_fromstr(&head_oid, "39467716290f6df775a91cdb9a4eb39295018145"); + git_oid__fromstr(&head_oid, "39467716290f6df775a91cdb9a4eb39295018145", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&head_commit, repo, &head_oid)); - git_oid_fromstr(&revert_oid, "ebb03002cee5d66c7732dd06241119fe72ab96a5"); + git_oid__fromstr(&revert_oid, "ebb03002cee5d66c7732dd06241119fe72ab96a5", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&revert_commit, repo, &revert_oid)); cl_git_pass(git_revert_commit(&index, repo, revert_commit, head_commit, 0, NULL)); diff --git a/tests/libgit2/revert/rename.c b/tests/libgit2/revert/rename.c index 0d713c60f..be7a98041 100644 --- a/tests/libgit2/revert/rename.c +++ b/tests/libgit2/revert/rename.c @@ -36,7 +36,7 @@ void test_revert_rename__automerge(void) cl_git_pass(git_repository_head(&head_ref, repo)); cl_git_pass(git_reference_peel((git_object **)&head_commit, head_ref, GIT_OBJECT_COMMIT)); - cl_git_pass(git_oid_fromstr(&revert_oid, "7b4d7c3789b3581973c04087cb774c3c3576de2f")); + cl_git_pass(git_oid__fromstr(&revert_oid, "7b4d7c3789b3581973c04087cb774c3c3576de2f", GIT_OID_SHA1)); cl_git_pass(git_commit_lookup(&revert_commit, repo, &revert_oid)); cl_git_pass(git_revert_commit(&index, repo, revert_commit, head_commit, 0, NULL)); diff --git a/tests/libgit2/revert/workdir.c b/tests/libgit2/revert/workdir.c index 3f54280ca..3e790b77f 100644 --- a/tests/libgit2/revert/workdir.c +++ b/tests/libgit2/revert/workdir.c @@ -45,11 +45,11 @@ void test_revert_workdir__automerge(void) { 0100644, "0f5bfcf58c558d865da6be0281d7795993646cee", 0, "file6.txt" }, }; - git_oid_fromstr(&head_oid, "72333f47d4e83616630ff3b0ffe4c0faebcc3c45"); + git_oid__fromstr(&head_oid, "72333f47d4e83616630ff3b0ffe4c0faebcc3c45", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&head, repo, &head_oid)); cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL)); - git_oid_fromstr(&revert_oid, "d1d403d22cbe24592d725f442835cf46fe60c8ac"); + git_oid__fromstr(&revert_oid, "d1d403d22cbe24592d725f442835cf46fe60c8ac", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &revert_oid)); cl_git_pass(git_revert(repo, commit, NULL)); @@ -76,7 +76,7 @@ void test_revert_workdir__conflicts(void) { 0100644, "0f5bfcf58c558d865da6be0281d7795993646cee", 0, "file6.txt" }, }; - git_oid_fromstr(&revert_oid, "72333f47d4e83616630ff3b0ffe4c0faebcc3c45"); + git_oid__fromstr(&revert_oid, "72333f47d4e83616630ff3b0ffe4c0faebcc3c45", GIT_OID_SHA1); cl_git_pass(git_repository_head(&head_ref, repo)); cl_git_pass(git_reference_peel((git_object **)&head, head_ref, GIT_OBJECT_COMMIT)); @@ -141,11 +141,11 @@ void test_revert_workdir__orphan(void) { 0100644, "296a6d3be1dff05c5d1f631d2459389fa7b619eb", 0, "file-mainline.txt" }, }; - git_oid_fromstr(&head_oid, "39467716290f6df775a91cdb9a4eb39295018145"); + git_oid__fromstr(&head_oid, "39467716290f6df775a91cdb9a4eb39295018145", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&head, repo, &head_oid)); cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL)); - git_oid_fromstr(&revert_oid, "ebb03002cee5d66c7732dd06241119fe72ab96a5"); + git_oid__fromstr(&revert_oid, "ebb03002cee5d66c7732dd06241119fe72ab96a5", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &revert_oid)); cl_git_pass(git_revert(repo, commit, NULL)); @@ -224,11 +224,11 @@ void test_revert_workdir__again_after_automerge(void) { 0100644, "0f5bfcf58c558d865da6be0281d7795993646cee", 0, "file6.txt" }, }; - git_oid_fromstr(&head_oid, "72333f47d4e83616630ff3b0ffe4c0faebcc3c45"); + git_oid__fromstr(&head_oid, "72333f47d4e83616630ff3b0ffe4c0faebcc3c45", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&head, repo, &head_oid)); cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL)); - git_oid_fromstr(&revert_oid, "d1d403d22cbe24592d725f442835cf46fe60c8ac"); + git_oid__fromstr(&revert_oid, "d1d403d22cbe24592d725f442835cf46fe60c8ac", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &revert_oid)); cl_git_pass(git_revert(repo, commit, NULL)); @@ -272,11 +272,11 @@ void test_revert_workdir__again_after_edit(void) cl_git_pass(git_repository_head(&head_ref, repo)); - cl_git_pass(git_oid_fromstr(&orig_head_oid, "399fb3aba3d9d13f7d40a9254ce4402067ef3149")); + cl_git_pass(git_oid__fromstr(&orig_head_oid, "399fb3aba3d9d13f7d40a9254ce4402067ef3149", GIT_OID_SHA1)); cl_git_pass(git_commit_lookup(&orig_head, repo, &orig_head_oid)); cl_git_pass(git_reset(repo, (git_object *)orig_head, GIT_RESET_HARD, NULL)); - cl_git_pass(git_oid_fromstr(&revert_oid, "2d440f2b3147d3dc7ad1085813478d6d869d5a4d")); + cl_git_pass(git_oid__fromstr(&revert_oid, "2d440f2b3147d3dc7ad1085813478d6d869d5a4d", GIT_OID_SHA1)); cl_git_pass(git_commit_lookup(&commit, repo, &revert_oid)); cl_git_pass(git_revert(repo, commit, NULL)); @@ -321,11 +321,11 @@ void test_revert_workdir__again_after_edit_two(void) cl_git_pass(git_repository_config(&config, repo)); cl_git_pass(git_config_set_bool(config, "core.autocrlf", 0)); - cl_git_pass(git_oid_fromstr(&head_commit_oid, "75ec9929465623f17ff3ad68c0438ea56faba815")); + cl_git_pass(git_oid__fromstr(&head_commit_oid, "75ec9929465623f17ff3ad68c0438ea56faba815", GIT_OID_SHA1)); cl_git_pass(git_commit_lookup(&head_commit, repo, &head_commit_oid)); cl_git_pass(git_reset(repo, (git_object *)head_commit, GIT_RESET_HARD, NULL)); - cl_git_pass(git_oid_fromstr(&revert_commit_oid, "97e52d5e81f541080cd6b92829fb85bc4d81d90b")); + cl_git_pass(git_oid__fromstr(&revert_commit_oid, "97e52d5e81f541080cd6b92829fb85bc4d81d90b", GIT_OID_SHA1)); cl_git_pass(git_commit_lookup(&revert_commit, repo, &revert_commit_oid)); cl_git_pass(git_revert(repo, revert_commit, NULL)); @@ -376,11 +376,11 @@ void test_revert_workdir__conflict_use_ours(void) opts.checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_USE_OURS; - git_oid_fromstr(&head_oid, "72333f47d4e83616630ff3b0ffe4c0faebcc3c45"); + git_oid__fromstr(&head_oid, "72333f47d4e83616630ff3b0ffe4c0faebcc3c45", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&head, repo, &head_oid)); cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL)); - git_oid_fromstr(&revert_oid, "d1d403d22cbe24592d725f442835cf46fe60c8ac"); + git_oid__fromstr(&revert_oid, "d1d403d22cbe24592d725f442835cf46fe60c8ac", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &revert_oid)); cl_git_pass(git_revert(repo, commit, &opts)); @@ -412,11 +412,11 @@ void test_revert_workdir__rename_1_of_2(void) opts.merge_opts.flags |= GIT_MERGE_FIND_RENAMES; opts.merge_opts.rename_threshold = 50; - git_oid_fromstr(&head_oid, "cef56612d71a6af8d8015691e4865f7fece905b5"); + git_oid__fromstr(&head_oid, "cef56612d71a6af8d8015691e4865f7fece905b5", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&head, repo, &head_oid)); cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL)); - git_oid_fromstr(&revert_oid, "55568c8de5322ff9a95d72747a239cdb64a19965"); + git_oid__fromstr(&revert_oid, "55568c8de5322ff9a95d72747a239cdb64a19965", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &revert_oid)); cl_git_pass(git_revert(repo, commit, &opts)); @@ -446,11 +446,11 @@ void test_revert_workdir__rename(void) opts.merge_opts.flags |= GIT_MERGE_FIND_RENAMES; opts.merge_opts.rename_threshold = 50; - git_oid_fromstr(&head_oid, "55568c8de5322ff9a95d72747a239cdb64a19965"); + git_oid__fromstr(&head_oid, "55568c8de5322ff9a95d72747a239cdb64a19965", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&head, repo, &head_oid)); cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL)); - git_oid_fromstr(&revert_oid, "0aa8c7e40d342fff78d60b29a4ba8e993ed79c51"); + git_oid__fromstr(&revert_oid, "0aa8c7e40d342fff78d60b29a4ba8e993ed79c51", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&commit, repo, &revert_oid)); cl_git_pass(git_revert(repo, commit, &opts)); @@ -512,7 +512,7 @@ void test_revert_workdir__merge_fails_without_mainline_specified(void) git_commit *head; git_oid head_oid; - git_oid_fromstr(&head_oid, "5acdc74af27172ec491d213ee36cea7eb9ef2579"); + git_oid__fromstr(&head_oid, "5acdc74af27172ec491d213ee36cea7eb9ef2579", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&head, repo, &head_oid)); cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL)); @@ -539,7 +539,7 @@ void test_revert_workdir__merge_first_parent(void) opts.mainline = 1; - git_oid_fromstr(&head_oid, "5acdc74af27172ec491d213ee36cea7eb9ef2579"); + git_oid__fromstr(&head_oid, "5acdc74af27172ec491d213ee36cea7eb9ef2579", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&head, repo, &head_oid)); cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL)); @@ -564,7 +564,7 @@ void test_revert_workdir__merge_second_parent(void) opts.mainline = 2; - git_oid_fromstr(&head_oid, "5acdc74af27172ec491d213ee36cea7eb9ef2579"); + git_oid__fromstr(&head_oid, "5acdc74af27172ec491d213ee36cea7eb9ef2579", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&head, repo, &head_oid)); cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL)); diff --git a/tests/libgit2/revwalk/basic.c b/tests/libgit2/revwalk/basic.c index 2c8d885e2..41090a1da 100644 --- a/tests/libgit2/revwalk/basic.c +++ b/tests/libgit2/revwalk/basic.c @@ -50,12 +50,12 @@ static const int result_bytes = 24; static int get_commit_index(git_oid *raw_oid) { int i; - char oid[GIT_OID_HEXSZ]; + char oid[GIT_OID_SHA1_HEXSIZE]; git_oid_fmt(oid, raw_oid); for (i = 0; i < commit_count; ++i) - if (memcmp(oid, commit_ids[i], GIT_OID_HEXSZ) == 0) + if (memcmp(oid, commit_ids[i], GIT_OID_SHA1_HEXSIZE) == 0) return i; return -1; @@ -75,9 +75,9 @@ static int test_walk_only(git_revwalk *walk, while (git_revwalk_next(&oid, walk) == 0) { result_array[i++] = get_commit_index(&oid); /*{ - char str[GIT_OID_HEXSZ+1]; + char str[GIT_OID_SHA1_HEXSIZE+1]; git_oid_fmt(str, &oid); - str[GIT_OID_HEXSZ] = 0; + str[GIT_OID_SHA1_HEXSIZE] = 0; printf(" %d) %s\n", i, str); }*/ } @@ -139,7 +139,7 @@ void test_revwalk_basic__sorting_modes(void) revwalk_basic_setup_walk(NULL); - git_oid_fromstr(&id, commit_head); + git_oid__fromstr(&id, commit_head, GIT_OID_SHA1); cl_git_pass(test_walk(_walk, &id, GIT_SORT_TIME, commit_sorting_time, 1)); cl_git_pass(test_walk(_walk, &id, GIT_SORT_TOPOLOGICAL, commit_sorting_topo, 2)); @@ -180,6 +180,23 @@ void test_revwalk_basic__glob_heads_with_invalid(void) cl_assert_equal_i(20, i); } +void test_revwalk_basic__glob_invalid_symbolic_ref(void) +{ + int i; + git_oid oid; + + revwalk_basic_setup_walk("testrepo"); + + cl_git_mkfile("testrepo/.git/refs/heads/broken-sym-ref", "ref: refs/heads/does-not-exist"); + cl_git_pass(git_revwalk_push_glob(_walk, "heads")); + + for (i = 0; !git_revwalk_next(&oid, _walk); ++i) + /* walking */; + + /* git log --branches --oneline | wc -l => 16 */ + cl_assert_equal_i(20, i); +} + void test_revwalk_basic__push_head(void) { int i = 0; @@ -204,7 +221,7 @@ void test_revwalk_basic__sorted_after_reset(void) revwalk_basic_setup_walk(NULL); - git_oid_fromstr(&oid, commit_head); + git_oid__fromstr(&oid, commit_head, GIT_OID_SHA1); /* push, sort, and test the walk */ cl_git_pass(git_revwalk_push(_walk, &oid)); @@ -282,7 +299,7 @@ void test_revwalk_basic__multiple_push_1(void) cl_git_pass(git_revwalk_hide_ref(_walk, "refs/heads/packed-test")); - cl_git_pass(git_oid_fromstr(&oid, "5b5b025afb0b4c913b4c338a42934a3863bf3644")); + cl_git_pass(git_oid__fromstr(&oid, "5b5b025afb0b4c913b4c338a42934a3863bf3644", GIT_OID_SHA1)); cl_git_pass(git_revwalk_push(_walk, &oid)); while (git_revwalk_next(&oid, _walk) == 0) @@ -316,7 +333,7 @@ void test_revwalk_basic__multiple_push_2(void) revwalk_basic_setup_walk(NULL); - cl_git_pass(git_oid_fromstr(&oid, "5b5b025afb0b4c913b4c338a42934a3863bf3644")); + cl_git_pass(git_oid__fromstr(&oid, "5b5b025afb0b4c913b4c338a42934a3863bf3644", GIT_OID_SHA1)); cl_git_pass(git_revwalk_push(_walk, &oid)); cl_git_pass(git_revwalk_hide_ref(_walk, "refs/heads/packed-test")); @@ -335,7 +352,7 @@ void test_revwalk_basic__disallow_non_commit(void) revwalk_basic_setup_walk(NULL); - cl_git_pass(git_oid_fromstr(&oid, "521d87c1ec3aef9824daf6d96cc0ae3710766d91")); + cl_git_pass(git_oid__fromstr(&oid, "521d87c1ec3aef9824daf6d96cc0ae3710766d91", GIT_OID_SHA1)); cl_git_fail(git_revwalk_push(_walk, &oid)); } @@ -345,7 +362,7 @@ void test_revwalk_basic__hide_then_push(void) int i = 0; revwalk_basic_setup_walk(NULL); - cl_git_pass(git_oid_fromstr(&oid, "5b5b025afb0b4c913b4c338a42934a3863bf3644")); + cl_git_pass(git_oid__fromstr(&oid, "5b5b025afb0b4c913b4c338a42934a3863bf3644", GIT_OID_SHA1)); cl_git_pass(git_revwalk_hide(_walk, &oid)); cl_git_pass(git_revwalk_push(_walk, &oid)); @@ -359,7 +376,7 @@ void test_revwalk_basic__hide_then_push(void) void test_revwalk_basic__topo_crash(void) { git_oid oid; - git_oid_fromstr(&oid, "5b5b025afb0b4c913b4c338a42934a3863bf3644"); + git_oid__fromstr(&oid, "5b5b025afb0b4c913b4c338a42934a3863bf3644", GIT_OID_SHA1); revwalk_basic_setup_walk(NULL); git_revwalk_sorting(_walk, GIT_SORT_TOPOLOGICAL); @@ -378,8 +395,8 @@ void test_revwalk_basic__from_new_to_old(void) revwalk_basic_setup_walk(NULL); git_revwalk_sorting(_walk, GIT_SORT_TIME); - cl_git_pass(git_oid_fromstr(&to_oid, "5b5b025afb0b4c913b4c338a42934a3863bf3644")); - cl_git_pass(git_oid_fromstr(&from_oid, "a4a7dce85cf63874e984719f4fdd239f5145052f")); + cl_git_pass(git_oid__fromstr(&to_oid, "5b5b025afb0b4c913b4c338a42934a3863bf3644", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&from_oid, "a4a7dce85cf63874e984719f4fdd239f5145052f", GIT_OID_SHA1)); cl_git_pass(git_revwalk_push(_walk, &to_oid)); cl_git_pass(git_revwalk_hide(_walk, &from_oid)); @@ -479,7 +496,7 @@ void test_revwalk_basic__mimic_git_rev_list(void) cl_git_pass(git_revwalk_push_ref(_walk, "refs/heads/br2")); cl_git_pass(git_revwalk_push_ref(_walk, "refs/heads/master")); - cl_git_pass(git_oid_fromstr(&oid, "e90810b8df3e80c413d903f631643c716887138d")); + cl_git_pass(git_oid__fromstr(&oid, "e90810b8df3e80c413d903f631643c716887138d", GIT_OID_SHA1)); cl_git_pass(git_revwalk_push(_walk, &oid)); cl_git_pass(git_revwalk_next(&oid, _walk)); @@ -563,10 +580,10 @@ void test_revwalk_basic__old_hidden_commit_one(void) revwalk_basic_setup_walk("testrepo.git"); - cl_git_pass(git_oid_fromstr(&new_id, "bd758010071961f28336333bc41e9c64c9a64866")); + cl_git_pass(git_oid__fromstr(&new_id, "bd758010071961f28336333bc41e9c64c9a64866", GIT_OID_SHA1)); cl_git_pass(git_revwalk_push(_walk, &new_id)); - cl_git_pass(git_oid_fromstr(&old_id, "8e73b769e97678d684b809b163bebdae2911720f")); + cl_git_pass(git_oid__fromstr(&old_id, "8e73b769e97678d684b809b163bebdae2911720f", GIT_OID_SHA1)); cl_git_pass(git_revwalk_hide(_walk, &old_id)); cl_git_pass(git_revwalk_next(&oid, _walk)); @@ -587,10 +604,10 @@ void test_revwalk_basic__old_hidden_commit_two(void) revwalk_basic_setup_walk("testrepo.git"); - cl_git_pass(git_oid_fromstr(&new_id, "bd758010071961f28336333bc41e9c64c9a64866")); + cl_git_pass(git_oid__fromstr(&new_id, "bd758010071961f28336333bc41e9c64c9a64866", GIT_OID_SHA1)); cl_git_pass(git_revwalk_push(_walk, &new_id)); - cl_git_pass(git_oid_fromstr(&old_id, "b91e763008b10db366442469339f90a2b8400d0a")); + cl_git_pass(git_oid__fromstr(&old_id, "b91e763008b10db366442469339f90a2b8400d0a", GIT_OID_SHA1)); cl_git_pass(git_revwalk_hide(_walk, &old_id)); cl_git_pass(git_revwalk_next(&oid, _walk)); diff --git a/tests/libgit2/revwalk/hidecb.c b/tests/libgit2/revwalk/hidecb.c index 54315bc77..2100a54f2 100644 --- a/tests/libgit2/revwalk/hidecb.c +++ b/tests/libgit2/revwalk/hidecb.c @@ -32,10 +32,10 @@ void test_revwalk_hidecb__initialize(void) int i; cl_git_pass(git_repository_open(&_repo, cl_fixture("testrepo.git"))); - cl_git_pass(git_oid_fromstr(&_head_id, commit_head)); + cl_git_pass(git_oid__fromstr(&_head_id, commit_head, GIT_OID_SHA1)); for (i = 0; i < commit_count; i++) - cl_git_pass(git_oid_fromstr(&commit_ids[i], commit_strs[i])); + cl_git_pass(git_oid__fromstr(&commit_ids[i], commit_strs[i], GIT_OID_SHA1)); } diff --git a/tests/libgit2/revwalk/mergebase.c b/tests/libgit2/revwalk/mergebase.c index 0378c869b..d413a1f6e 100644 --- a/tests/libgit2/revwalk/mergebase.c +++ b/tests/libgit2/revwalk/mergebase.c @@ -25,9 +25,9 @@ void test_revwalk_mergebase__single1(void) git_oid result, one, two, expected; size_t ahead, behind; - cl_git_pass(git_oid_fromstr(&one, "c47800c7266a2be04c571c04d5a6614691ea99bd ")); - cl_git_pass(git_oid_fromstr(&two, "9fd738e8f7967c078dceed8190330fc8648ee56a")); - cl_git_pass(git_oid_fromstr(&expected, "5b5b025afb0b4c913b4c338a42934a3863bf3644")); + cl_git_pass(git_oid__fromstr(&one, "c47800c7266a2be04c571c04d5a6614691ea99bd ", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&two, "9fd738e8f7967c078dceed8190330fc8648ee56a", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&expected, "5b5b025afb0b4c913b4c338a42934a3863bf3644", GIT_OID_SHA1)); cl_git_pass(git_merge_base(&result, _repo, &one, &two)); cl_assert_equal_oid(&expected, &result); @@ -46,9 +46,9 @@ void test_revwalk_mergebase__single2(void) git_oid result, one, two, expected; size_t ahead, behind; - cl_git_pass(git_oid_fromstr(&one, "763d71aadf09a7951596c9746c024e7eece7c7af")); - cl_git_pass(git_oid_fromstr(&two, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750")); - cl_git_pass(git_oid_fromstr(&expected, "c47800c7266a2be04c571c04d5a6614691ea99bd")); + cl_git_pass(git_oid__fromstr(&one, "763d71aadf09a7951596c9746c024e7eece7c7af", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&two, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&expected, "c47800c7266a2be04c571c04d5a6614691ea99bd", GIT_OID_SHA1)); cl_git_pass(git_merge_base(&result, _repo, &one, &two)); cl_assert_equal_oid(&expected, &result); @@ -67,9 +67,9 @@ void test_revwalk_mergebase__merged_branch(void) git_oid result, one, two, expected; size_t ahead, behind; - cl_git_pass(git_oid_fromstr(&one, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750")); - cl_git_pass(git_oid_fromstr(&two, "9fd738e8f7967c078dceed8190330fc8648ee56a")); - cl_git_pass(git_oid_fromstr(&expected, "9fd738e8f7967c078dceed8190330fc8648ee56a")); + cl_git_pass(git_oid__fromstr(&one, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&two, "9fd738e8f7967c078dceed8190330fc8648ee56a", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&expected, "9fd738e8f7967c078dceed8190330fc8648ee56a", GIT_OID_SHA1)); cl_git_pass(git_merge_base(&result, _repo, &one, &two)); cl_assert_equal_oid(&expected, &result); @@ -91,8 +91,8 @@ void test_revwalk_mergebase__two_way_merge(void) git_oid one, two; size_t ahead, behind; - cl_git_pass(git_oid_fromstr(&one, "9b219343610c88a1187c996d0dc58330b55cee28")); - cl_git_pass(git_oid_fromstr(&two, "a953a018c5b10b20c86e69fef55ebc8ad4c5a417")); + cl_git_pass(git_oid__fromstr(&one, "9b219343610c88a1187c996d0dc58330b55cee28", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&two, "a953a018c5b10b20c86e69fef55ebc8ad4c5a417", GIT_OID_SHA1)); cl_git_pass(git_graph_ahead_behind(&ahead, &behind, _repo2, &one, &two)); cl_assert_equal_sz(ahead, 8); @@ -110,8 +110,8 @@ void test_revwalk_mergebase__no_common_ancestor_returns_ENOTFOUND(void) size_t ahead, behind; int error; - cl_git_pass(git_oid_fromstr(&one, "763d71aadf09a7951596c9746c024e7eece7c7af")); - cl_git_pass(git_oid_fromstr(&two, "e90810b8df3e80c413d903f631643c716887138d")); + cl_git_pass(git_oid__fromstr(&one, "763d71aadf09a7951596c9746c024e7eece7c7af", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&two, "e90810b8df3e80c413d903f631643c716887138d", GIT_OID_SHA1)); error = git_merge_base(&result, _repo, &one, &two); cl_git_fail(error); @@ -127,9 +127,9 @@ void test_revwalk_mergebase__prefer_youngest_merge_base(void) { git_oid result, one, two, expected; - cl_git_pass(git_oid_fromstr(&one, "a4a7dce85cf63874e984719f4fdd239f5145052f")); - cl_git_pass(git_oid_fromstr(&two, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644")); - cl_git_pass(git_oid_fromstr(&expected, "c47800c7266a2be04c571c04d5a6614691ea99bd")); + cl_git_pass(git_oid__fromstr(&one, "a4a7dce85cf63874e984719f4fdd239f5145052f", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&two, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&expected, "c47800c7266a2be04c571c04d5a6614691ea99bd", GIT_OID_SHA1)); cl_git_pass(git_merge_base(&result, _repo, &one, &two)); cl_assert_equal_oid(&expected, &result); @@ -140,10 +140,10 @@ void test_revwalk_mergebase__multiple_merge_bases(void) git_oid one, two, expected1, expected2; git_oidarray result = {NULL, 0}; - cl_git_pass(git_oid_fromstr(&one, "a4a7dce85cf63874e984719f4fdd239f5145052f")); - cl_git_pass(git_oid_fromstr(&two, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644")); - cl_git_pass(git_oid_fromstr(&expected1, "c47800c7266a2be04c571c04d5a6614691ea99bd")); - cl_git_pass(git_oid_fromstr(&expected2, "9fd738e8f7967c078dceed8190330fc8648ee56a")); + cl_git_pass(git_oid__fromstr(&one, "a4a7dce85cf63874e984719f4fdd239f5145052f", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&two, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&expected1, "c47800c7266a2be04c571c04d5a6614691ea99bd", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&expected2, "9fd738e8f7967c078dceed8190330fc8648ee56a", GIT_OID_SHA1)); cl_git_pass(git_merge_bases(&result, _repo, &one, &two)); cl_assert_equal_i(2, result.count); @@ -160,10 +160,10 @@ void test_revwalk_mergebase__multiple_merge_bases_many_commits(void) git_oid *input = git__malloc(sizeof(git_oid) * 2); - cl_git_pass(git_oid_fromstr(&input[0], "a4a7dce85cf63874e984719f4fdd239f5145052f")); - cl_git_pass(git_oid_fromstr(&input[1], "be3563ae3f795b2b4353bcce3a527ad0a4f7f644")); - cl_git_pass(git_oid_fromstr(&expected1, "c47800c7266a2be04c571c04d5a6614691ea99bd")); - cl_git_pass(git_oid_fromstr(&expected2, "9fd738e8f7967c078dceed8190330fc8648ee56a")); + cl_git_pass(git_oid__fromstr(&input[0], "a4a7dce85cf63874e984719f4fdd239f5145052f", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&input[1], "be3563ae3f795b2b4353bcce3a527ad0a4f7f644", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&expected1, "c47800c7266a2be04c571c04d5a6614691ea99bd", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&expected2, "9fd738e8f7967c078dceed8190330fc8648ee56a", GIT_OID_SHA1)); cl_git_pass(git_merge_bases_many(&result, _repo, 2, input)); cl_assert_equal_i(2, result.count); @@ -178,8 +178,8 @@ void test_revwalk_mergebase__no_off_by_one_missing(void) { git_oid result, one, two; - cl_git_pass(git_oid_fromstr(&one, "1a443023183e3f2bfbef8ac923cd81c1018a18fd")); - cl_git_pass(git_oid_fromstr(&two, "9f13f7d0a9402c681f91dc590cf7b5470e6a77d2")); + cl_git_pass(git_oid__fromstr(&one, "1a443023183e3f2bfbef8ac923cd81c1018a18fd", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&two, "9f13f7d0a9402c681f91dc590cf7b5470e6a77d2", GIT_OID_SHA1)); cl_git_pass(git_merge_base(&result, _repo, &one, &two)); } @@ -201,7 +201,7 @@ static void assert_mergebase_many(const char *expected_sha, int count, ...) for (i = 0; i < count; ++i) { partial_oid = va_arg(ap, char *); - cl_git_pass(git_oid_fromstrn(&oid, partial_oid, strlen(partial_oid))); + cl_git_pass(git_oid__fromstrn(&oid, partial_oid, strlen(partial_oid), GIT_OID_SHA1)); cl_git_pass(git_object_lookup_prefix(&object, _repo, &oid, strlen(partial_oid), GIT_OBJECT_COMMIT)); git_oid_cpy(&oids[i], git_object_id(object)); @@ -214,7 +214,7 @@ static void assert_mergebase_many(const char *expected_sha, int count, ...) cl_assert_equal_i(GIT_ENOTFOUND, git_merge_base_many(&oid, _repo, count, oids)); else { cl_git_pass(git_merge_base_many(&oid, _repo, count, oids)); - cl_git_pass(git_oid_fromstr(&expected, expected_sha)); + cl_git_pass(git_oid__fromstr(&expected, expected_sha, GIT_OID_SHA1)); cl_assert_equal_oid(&expected, &oid); } @@ -265,7 +265,7 @@ static void assert_mergebase_octopus(const char *expected_sha, int count, ...) for (i = 0; i < count; ++i) { partial_oid = va_arg(ap, char *); - cl_git_pass(git_oid_fromstrn(&oid, partial_oid, strlen(partial_oid))); + cl_git_pass(git_oid__fromstrn(&oid, partial_oid, strlen(partial_oid), GIT_OID_SHA1)); cl_git_pass(git_object_lookup_prefix(&object, _repo, &oid, strlen(partial_oid), GIT_OBJECT_COMMIT)); git_oid_cpy(&oids[i], git_object_id(object)); @@ -278,7 +278,7 @@ static void assert_mergebase_octopus(const char *expected_sha, int count, ...) cl_assert_equal_i(GIT_ENOTFOUND, git_merge_base_octopus(&oid, _repo, count, oids)); else { cl_git_pass(git_merge_base_octopus(&oid, _repo, count, oids)); - cl_git_pass(git_oid_fromstr(&expected, expected_sha)); + cl_git_pass(git_oid__fromstr(&expected, expected_sha, GIT_OID_SHA1)); cl_assert_equal_oid(&expected, &oid); } @@ -501,9 +501,9 @@ void test_revwalk_mergebase__remove_redundant(void) cl_git_pass(git_repository_open(&repo, cl_fixture("redundant.git"))); - cl_git_pass(git_oid_fromstr(&one, "d89137c93ba1ee749214ff4ce52ae9137bc833f9")); - cl_git_pass(git_oid_fromstr(&two, "91f4b95df4a59504a9813ba66912562931d990e3")); - cl_git_pass(git_oid_fromstr(&base, "6cb1f2352d974e1c5a776093017e8772416ac97a")); + cl_git_pass(git_oid__fromstr(&one, "d89137c93ba1ee749214ff4ce52ae9137bc833f9", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&two, "91f4b95df4a59504a9813ba66912562931d990e3", GIT_OID_SHA1)); + cl_git_pass(git_oid__fromstr(&base, "6cb1f2352d974e1c5a776093017e8772416ac97a", GIT_OID_SHA1)); cl_git_pass(git_merge_bases(&result, repo, &one, &two)); cl_assert_equal_i(1, result.count); diff --git a/tests/libgit2/revwalk/simplify.c b/tests/libgit2/revwalk/simplify.c index 6dd068a42..824496d7e 100644 --- a/tests/libgit2/revwalk/simplify.c +++ b/tests/libgit2/revwalk/simplify.c @@ -32,13 +32,13 @@ void test_revwalk_simplify__first_parent(void) int i, error; for (i = 0; i < 4; i++) { - git_oid_fromstr(&expected[i], expected_str[i]); + git_oid__fromstr(&expected[i], expected_str[i], GIT_OID_SHA1); } repo = cl_git_sandbox_init("testrepo.git"); cl_git_pass(git_revwalk_new(&walk, repo)); - git_oid_fromstr(&id, commit_head); + git_oid__fromstr(&id, commit_head, GIT_OID_SHA1); cl_git_pass(git_revwalk_push(walk, &id)); git_revwalk_sorting(walk, GIT_SORT_TOPOLOGICAL); git_revwalk_simplify_first_parent(walk); diff --git a/tests/libgit2/stash/save.c b/tests/libgit2/stash/save.c index f574211d7..23f3c1cbb 100644 --- a/tests/libgit2/stash/save.c +++ b/tests/libgit2/stash/save.c @@ -130,6 +130,19 @@ void test_stash_save__can_keep_index(void) assert_status(repo, "just.ignore", GIT_STATUS_IGNORED); } +void test_stash_save__can_keep_all(void) +{ + cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_KEEP_ALL)); + + assert_status(repo, "what", GIT_STATUS_WT_MODIFIED | GIT_STATUS_INDEX_MODIFIED); + assert_status(repo, "how", GIT_STATUS_INDEX_MODIFIED); + assert_status(repo, "who", GIT_STATUS_WT_MODIFIED); + assert_status(repo, "when", GIT_STATUS_WT_NEW); + assert_status(repo, "why", GIT_STATUS_INDEX_NEW); + assert_status(repo, "where", GIT_STATUS_WT_MODIFIED | GIT_STATUS_INDEX_NEW); + assert_status(repo, "just.ignore", GIT_STATUS_IGNORED); +} + static void assert_commit_message_contains(const char *revision, const char *fragment) { git_commit *commit; @@ -488,3 +501,27 @@ void test_stash_save__deleted_in_index_modified_in_workdir(void) git_index_free(index); } + +void test_stash_save__option_paths(void) +{ + git_stash_save_options options = GIT_STASH_SAVE_OPTIONS_INIT; + char *paths[2] = { "who", "where" }; + + options.paths = (git_strarray){ + paths, + 2 + }; + options.stasher = signature; + + cl_git_pass(git_stash_save_with_opts(&stash_tip_oid, repo, &options)); + + assert_blob_oid("refs/stash:who", "a0400d4954659306a976567af43125a0b1aa8595"); + assert_blob_oid("refs/stash:where", "e3d6434ec12eb76af8dfa843a64ba6ab91014a0b"); + + assert_blob_oid("refs/stash:what", "ce013625030ba8dba906f756967f9e9ca394464a"); + assert_blob_oid("refs/stash:how", "ac790413e2d7a26c3767e78c57bb28716686eebc"); + assert_blob_oid("refs/stash:when", NULL); + assert_blob_oid("refs/stash:why", NULL); + assert_blob_oid("refs/stash:.gitignore", "ac4d88de61733173d9959e4b77c69b9f17a00980"); + assert_blob_oid("refs/stash:just.ignore", NULL); +} diff --git a/tests/libgit2/status/single.c b/tests/libgit2/status/single.c index e7f92097c..b9659a031 100644 --- a/tests/libgit2/status/single.c +++ b/tests/libgit2/status/single.c @@ -1,5 +1,6 @@ #include "clar_libgit2.h" #include "posix.h" +#include "odb.h" static void cleanup__remove_file(void *_file) @@ -17,11 +18,11 @@ void test_status_single__hash_single_file(void) git_oid expected_id, actual_id; /* initialization */ - git_oid_fromstr(&expected_id, file_hash); + git_oid__fromstr(&expected_id, file_hash, GIT_OID_SHA1); cl_git_mkfile(file_name, file_contents); cl_set_cleanup(&cleanup__remove_file, (void *)file_name); - cl_git_pass(git_odb_hashfile(&actual_id, file_name, GIT_OBJECT_BLOB)); + cl_git_pass(git_odb__hashfile(&actual_id, file_name, GIT_OBJECT_BLOB, GIT_OID_SHA1)); cl_assert_equal_oid(&expected_id, &actual_id); } @@ -35,11 +36,11 @@ void test_status_single__hash_single_empty_file(void) git_oid expected_id, actual_id; /* initialization */ - git_oid_fromstr(&expected_id, file_hash); + git_oid__fromstr(&expected_id, file_hash, GIT_OID_SHA1); cl_git_mkfile(file_name, file_contents); cl_set_cleanup(&cleanup__remove_file, (void *)file_name); - cl_git_pass(git_odb_hashfile(&actual_id, file_name, GIT_OBJECT_BLOB)); + cl_git_pass(git_odb__hashfile(&actual_id, file_name, GIT_OBJECT_BLOB, GIT_OID_SHA1)); cl_assert_equal_oid(&expected_id, &actual_id); } diff --git a/tests/libgit2/status/submodules.c b/tests/libgit2/status/submodules.c index d223657b4..90d56d9cc 100644 --- a/tests/libgit2/status/submodules.c +++ b/tests/libgit2/status/submodules.c @@ -142,7 +142,7 @@ void test_status_submodules__moved_head(void) /* move submodule HEAD to c47800c7266a2be04c571c04d5a6614691ea99bd */ cl_git_pass( - git_oid_fromstr(&oid, "c47800c7266a2be04c571c04d5a6614691ea99bd")); + git_oid__fromstr(&oid, "c47800c7266a2be04c571c04d5a6614691ea99bd", GIT_OID_SHA1)); cl_git_pass(git_repository_set_head_detached(smrepo, &oid)); /* first do a normal status, which should now include the submodule */ diff --git a/tests/libgit2/status/worktree.c b/tests/libgit2/status/worktree.c index 00c6ec2d5..efbf597a7 100644 --- a/tests/libgit2/status/worktree.c +++ b/tests/libgit2/status/worktree.c @@ -515,18 +515,21 @@ void test_status_worktree__conflict_with_diff3(void) ancestor_entry.path = "modified_file"; ancestor_entry.mode = 0100644; - git_oid_fromstr(&ancestor_entry.id, - "452e4244b5d083ddf0460acf1ecc74db9dcfa11a"); + git_oid__fromstr(&ancestor_entry.id, + "452e4244b5d083ddf0460acf1ecc74db9dcfa11a", + GIT_OID_SHA1); our_entry.path = "modified_file"; our_entry.mode = 0100644; - git_oid_fromstr(&our_entry.id, - "452e4244b5d083ddf0460acf1ecc74db9dcfa11a"); + git_oid__fromstr(&our_entry.id, + "452e4244b5d083ddf0460acf1ecc74db9dcfa11a", + GIT_OID_SHA1); their_entry.path = "modified_file"; their_entry.mode = 0100644; - git_oid_fromstr(&their_entry.id, - "452e4244b5d083ddf0460acf1ecc74db9dcfa11a"); + git_oid__fromstr(&their_entry.id, + "452e4244b5d083ddf0460acf1ecc74db9dcfa11a", + GIT_OID_SHA1); cl_git_pass(git_status_file(&status, repo, "modified_file")); cl_assert_equal_i(GIT_STATUS_WT_MODIFIED, status); @@ -711,18 +714,21 @@ void test_status_worktree__conflicted_item(void) ancestor_entry.mode = 0100644; ancestor_entry.path = "modified_file"; - git_oid_fromstr(&ancestor_entry.id, - "452e4244b5d083ddf0460acf1ecc74db9dcfa11a"); + git_oid__fromstr(&ancestor_entry.id, + "452e4244b5d083ddf0460acf1ecc74db9dcfa11a", + GIT_OID_SHA1); our_entry.mode = 0100644; our_entry.path = "modified_file"; - git_oid_fromstr(&our_entry.id, - "452e4244b5d083ddf0460acf1ecc74db9dcfa11a"); + git_oid__fromstr(&our_entry.id, + "452e4244b5d083ddf0460acf1ecc74db9dcfa11a", + GIT_OID_SHA1); their_entry.mode = 0100644; their_entry.path = "modified_file"; - git_oid_fromstr(&their_entry.id, - "452e4244b5d083ddf0460acf1ecc74db9dcfa11a"); + git_oid__fromstr(&their_entry.id, + "452e4244b5d083ddf0460acf1ecc74db9dcfa11a", + GIT_OID_SHA1); cl_git_pass(git_status_file(&status, repo, "modified_file")); cl_assert_equal_i(GIT_STATUS_WT_MODIFIED, status); @@ -744,11 +750,11 @@ void test_status_worktree__conflict_has_no_oid(void) git_index_entry entry = {{0}}; git_status_list *statuslist; const git_status_entry *status; - git_oid zero_id = {{0}}; + git_oid zero_id = GIT_OID_SHA1_ZERO; entry.mode = 0100644; entry.path = "modified_file"; - git_oid_fromstr(&entry.id, "452e4244b5d083ddf0460acf1ecc74db9dcfa11a"); + git_oid__fromstr(&entry.id, "452e4244b5d083ddf0460acf1ecc74db9dcfa11a", GIT_OID_SHA1); cl_git_pass(git_repository_index(&index, repo)); cl_git_pass(git_index_conflict_add(index, &entry, &entry, &entry)); diff --git a/tests/libgit2/submodule/add.c b/tests/libgit2/submodule/add.c index ae5507d7f..a2a66e7f5 100644 --- a/tests/libgit2/submodule/add.c +++ b/tests/libgit2/submodule/add.c @@ -139,7 +139,7 @@ static void test_add_entry( { git_index_entry entry = {{0}}; - cl_git_pass(git_oid_fromstr(&entry.id, idstr)); + cl_git_pass(git_oid__fromstr(&entry.id, idstr, GIT_OID_SHA1)); entry.path = path; entry.mode = mode; diff --git a/tests/libgit2/submodule/update.c b/tests/libgit2/submodule/update.c index 4aa959852..052a4a1fe 100644 --- a/tests/libgit2/submodule/update.c +++ b/tests/libgit2/submodule/update.c @@ -206,6 +206,26 @@ void test_submodule_update__update_and_init_submodule(void) git_submodule_free(sm); } +void test_submodule_update__update_skip_configured_missing_submodule(void) +{ + git_submodule *sm; + git_submodule_update_options update_options = GIT_SUBMODULE_UPDATE_OPTIONS_INIT; + unsigned int submodule_status = 0; + + g_repo = setup_fixture_submod2(); + + /* get the submodule */ + cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_gitmodules_only")); + + cl_git_pass(git_submodule_status(&submodule_status, g_repo, "sm_gitmodules_only", GIT_SUBMODULE_IGNORE_UNSPECIFIED)); + cl_assert_equal_i(submodule_status, GIT_SUBMODULE_STATUS_IN_CONFIG); + + /* update (with option to initialize sub repo) */ + cl_git_pass(git_submodule_update(sm, 1, &update_options)); + + git_submodule_free(sm); +} + void test_submodule_update__update_already_checked_out_submodule(void) { git_submodule *sm = NULL; diff --git a/tests/libgit2/transports/smart/packet.c b/tests/libgit2/transports/smart/packet.c index 5b623a378..2035e3b65 100644 --- a/tests/libgit2/transports/smart/packet.c +++ b/tests/libgit2/transports/smart/packet.c @@ -11,8 +11,9 @@ static void assert_flush_parses(const char *line) size_t linelen = strlen(line) + 1; const char *endptr; git_pkt *pkt; + git_pkt_parse_data pkt_parse_data = { 0 }; - cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen)); + cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen, &pkt_parse_data)); cl_assert_equal_i(pkt->type, GIT_PKT_FLUSH); cl_assert_equal_strn(endptr, line + 4, linelen - 4); @@ -24,8 +25,9 @@ static void assert_data_pkt_parses(const char *line, const char *expected_data, size_t linelen = strlen(line) + 1; const char *endptr; git_pkt_data *pkt; + git_pkt_parse_data pkt_parse_data = { 0 }; - cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen)); + cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen, &pkt_parse_data)); cl_assert_equal_i(pkt->type, GIT_PKT_DATA); cl_assert_equal_i(pkt->len, expected_len); cl_assert_equal_strn(pkt->data, expected_data, expected_len); @@ -38,8 +40,9 @@ static void assert_sideband_progress_parses(const char *line, const char *expect size_t linelen = strlen(line) + 1; const char *endptr; git_pkt_progress *pkt; + git_pkt_parse_data pkt_parse_data = { 0 }; - cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen)); + cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen, &pkt_parse_data)); cl_assert_equal_i(pkt->type, GIT_PKT_PROGRESS); cl_assert_equal_i(pkt->len, expected_len); cl_assert_equal_strn(pkt->data, expected_data, expected_len); @@ -52,8 +55,9 @@ static void assert_error_parses(const char *line, const char *expected_error, si size_t linelen = strlen(line) + 1; const char *endptr; git_pkt_err *pkt; + git_pkt_parse_data pkt_parse_data = { 0 }; - cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen)); + cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen, &pkt_parse_data)); cl_assert_equal_i(pkt->type, GIT_PKT_ERR); cl_assert_equal_i(pkt->len, expected_len); cl_assert_equal_strn(pkt->error, expected_error, expected_len); @@ -67,10 +71,11 @@ static void assert_ack_parses(const char *line, const char *expected_oid, enum g const char *endptr; git_pkt_ack *pkt; git_oid oid; + git_pkt_parse_data pkt_parse_data = { 0 }; - cl_git_pass(git_oid_fromstr(&oid, expected_oid)); + cl_git_pass(git_oid__fromstr(&oid, expected_oid, GIT_OID_SHA1)); - cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen)); + cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen, &pkt_parse_data)); cl_assert_equal_i(pkt->type, GIT_PKT_ACK); cl_assert_equal_oid(&pkt->oid, &oid); cl_assert_equal_i(pkt->status, expected_status); @@ -83,8 +88,9 @@ static void assert_nak_parses(const char *line) size_t linelen = strlen(line) + 1; const char *endptr; git_pkt *pkt; + git_pkt_parse_data pkt_parse_data = { 0 }; - cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen)); + cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen, &pkt_parse_data)); cl_assert_equal_i(pkt->type, GIT_PKT_NAK); cl_assert_equal_strn(endptr, line + 7, linelen - 7); @@ -96,8 +102,9 @@ static void assert_comment_parses(const char *line, const char *expected_comment size_t linelen = strlen(line) + 1; const char *endptr; git_pkt_comment *pkt; + git_pkt_parse_data pkt_parse_data = { 0 }; - cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen)); + cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen, &pkt_parse_data)); cl_assert_equal_i(pkt->type, GIT_PKT_COMMENT); cl_assert_equal_strn(pkt->comment, expected_comment, strlen(expected_comment)); @@ -109,8 +116,9 @@ static void assert_ok_parses(const char *line, const char *expected_ref) size_t linelen = strlen(line) + 1; const char *endptr; git_pkt_ok *pkt; + git_pkt_parse_data pkt_parse_data = { 0 }; - cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen)); + cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen, &pkt_parse_data)); cl_assert_equal_i(pkt->type, GIT_PKT_OK); cl_assert_equal_strn(pkt->ref, expected_ref, strlen(expected_ref)); @@ -122,8 +130,9 @@ static void assert_unpack_parses(const char *line, bool ok) size_t linelen = strlen(line) + 1; const char *endptr; git_pkt_unpack *pkt; + git_pkt_parse_data pkt_parse_data = { 0 }; - cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen)); + cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen, &pkt_parse_data)); cl_assert_equal_i(pkt->type, GIT_PKT_UNPACK); cl_assert_equal_i(pkt->unpack_ok, ok); @@ -135,8 +144,9 @@ static void assert_ng_parses(const char *line, const char *expected_ref, const c size_t linelen = strlen(line) + 1; const char *endptr; git_pkt_ng *pkt; + git_pkt_parse_data pkt_parse_data = { 0 }; - cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen)); + cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen, &pkt_parse_data)); cl_assert_equal_i(pkt->type, GIT_PKT_NG); cl_assert_equal_strn(pkt->ref, expected_ref, strlen(expected_ref)); cl_assert_equal_strn(pkt->msg, expected_msg, strlen(expected_msg)); @@ -153,10 +163,11 @@ static void assert_ref_parses_(const char *line, size_t linelen, const char *exp const char *endptr; git_pkt_ref *pkt; git_oid oid; + git_pkt_parse_data pkt_parse_data = { 0 }; - cl_git_pass(git_oid_fromstr(&oid, expected_oid)); + cl_git_pass(git_oid__fromstr(&oid, expected_oid, GIT_OID_SHA1)); - cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen)); + cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen, &pkt_parse_data)); cl_assert_equal_i(pkt->type, GIT_PKT_REF); cl_assert_equal_oid(&pkt->head.oid, &oid); cl_assert_equal_strn(pkt->head.name, expected_ref, strlen(expected_ref)); @@ -171,8 +182,10 @@ static void assert_ref_parses_(const char *line, size_t linelen, const char *exp static void assert_pkt_fails(const char *line) { const char *endptr; + git_pkt_parse_data pkt_parse_data = { 0 }; + git_pkt *pkt; - cl_git_fail(git_pkt_parse_line(&pkt, &endptr, line, strlen(line) + 1)); + cl_git_fail(git_pkt_parse_line(&pkt, &endptr, line, strlen(line) + 1, &pkt_parse_data)); } void test_transports_smart_packet__parsing_garbage_fails(void) diff --git a/tests/libgit2/win32/forbidden.c b/tests/libgit2/win32/forbidden.c index 5c007987b..c4e82e90d 100644 --- a/tests/libgit2/win32/forbidden.c +++ b/tests/libgit2/win32/forbidden.c @@ -37,7 +37,7 @@ void test_win32_forbidden__can_add_forbidden_filename_with_entry(void) entry.path = "aux"; entry.mode = GIT_FILEMODE_BLOB; - git_oid_fromstr(&entry.id, "da623abd956bb2fd8052c708c7ed43f05d192d37"); + git_oid__fromstr(&entry.id, "da623abd956bb2fd8052c708c7ed43f05d192d37", GIT_OID_SHA1); cl_git_pass(git_index_add(index, &entry)); @@ -53,7 +53,7 @@ void test_win32_forbidden__cannot_add_dot_git_even_with_entry(void) entry.path = "foo/.git"; entry.mode = GIT_FILEMODE_BLOB; - git_oid_fromstr(&entry.id, "da623abd956bb2fd8052c708c7ed43f05d192d37"); + git_oid__fromstr(&entry.id, "da623abd956bb2fd8052c708c7ed43f05d192d37", GIT_OID_SHA1); cl_git_fail(git_index_add(index, &entry)); diff --git a/tests/libgit2/win32/systemdir.c b/tests/libgit2/win32/systemdir.c index 52c1784a1..9039f05b2 100644 --- a/tests/libgit2/win32/systemdir.c +++ b/tests/libgit2/win32/systemdir.c @@ -1,7 +1,6 @@ #include "clar_libgit2.h" #include "futils.h" #include "sysdir.h" -#include "win32/findfile.h" #ifdef GIT_WIN32 static char *path_save; diff --git a/tests/libgit2/worktree/worktree.c b/tests/libgit2/worktree/worktree.c index 66273d1cb..9fd27f49c 100644 --- a/tests/libgit2/worktree/worktree.c +++ b/tests/libgit2/worktree/worktree.c @@ -120,7 +120,7 @@ void test_worktree_worktree__lookup_nonexistent_worktree(void) { git_worktree *wt; - cl_git_fail(git_worktree_lookup(&wt, fixture.repo, "nonexistent")); + cl_git_fail_with(GIT_ENOTFOUND, git_worktree_lookup(&wt, fixture.repo, "nonexistent")); cl_assert_equal_p(wt, NULL); } diff --git a/tests/resources/namespace.git/COMMIT_EDITMSG b/tests/resources/namespace.git/COMMIT_EDITMSG new file mode 100644 index 0000000000000000000000000000000000000000..8510665149157c2bc901848c3e0b746954e9cbd9 GIT binary patch literal 5 McmYexFD>E%00s;J#{d8T literal 0 HcmV?d00001 diff --git a/tests/resources/namespace.git/HEAD b/tests/resources/namespace.git/HEAD new file mode 100644 index 0000000000000000000000000000000000000000..60cbd742cb37d5686023ce891982230dfe0973ce GIT binary patch literal 21 ccmXR)O|w!cN=+-)&qz&7Db`QRFD>E%08;!1aR2}S literal 0 HcmV?d00001 diff --git a/tests/resources/namespace.git/config b/tests/resources/namespace.git/config new file mode 100644 index 0000000000000000000000000000000000000000..6c9406b7d9320db083eca69b3f8bee9a6c7b50d4 GIT binary patch literal 137 zcmYk#%?-jZ3KJaaM(b)IThRcka) zn6vinzTI-FENHqTG;JZL7ug4u#6zM7i5Th{J5BgE#z&9!LjG%xu(tTZ>RkRd-|~Df A#{d8T literal 0 HcmV?d00001 diff --git a/tests/resources/namespace.git/description b/tests/resources/namespace.git/description new file mode 100644 index 0000000000000000000000000000000000000000..498b267a8c7812490d6479839c5577eaaec79d62 GIT binary patch literal 73 zcmWH|%S+5nO;IRHEyyp$t+PQ$;d2LNXyJgRZve!Elw`VEGWs$&r??@ Q$yWgB0LrH#Y0~2Y0PnOK(EtDd literal 0 HcmV?d00001 diff --git a/tests/resources/namespace.git/index b/tests/resources/namespace.git/index new file mode 100644 index 0000000000000000000000000000000000000000..5ed27feb0636755a2a55a6ddf376fb411434c183 GIT binary patch literal 321 zcmZ?q402{*U|<4bmSm>(R(|Gx=U_A=P>fOYlQ9EB;}Ql2#;-s%A|Q2PYO6nd*NeEm zFxaenY3-I{#Rnc1GB6r40QI%Ye!VdPMnm;mpzHrG`TmN*RqgX9!m^w%To5@r#C0|IZac2%Pw`D=waxlFe!O&fJ{`%Aq9uv zF>x?43CC?98LgM74&mxQaZl`0_K~G!AJ1Fy+dOnv@BVm1RfBg`#}vQT^L}D;{a%(w zme)G7*_Vawm4($WaqMRnq_ra+gh)+8BB{ZV1t|znDKr$Mv(2bO(%QeJjs9EN{ZxLW zp}TO%#7&myvP?)ExzP@};D&orCbl3bZbUwmRSxp5>Mg4$Hl=O*ZT?>3&|Uw3+TXH% z2Yu20C)=+9xCUY98v_7LB9P)S8Re~U;1W8m9C-wTIg=noKC57k*x%;Co%x?Zz!@?z zbXV{Gc%ZWo+#T~pY3q`%y5@Rb`+-49A#zhrA?cP=Av0;TmXh?!1j}P=NpAgd1epIC K1<#?qvHb+E-pgA6 literal 0 HcmV?d00001 diff --git a/tests/resources/namespace.git/logs/refs/heads/branch b/tests/resources/namespace.git/logs/refs/heads/branch new file mode 100644 index 0000000000000000000000000000000000000000..e3dfea400d93a60567df2a0d0fc5765be66bbb20 GIT binary patch literal 500 zcmbWz&q~BV3mK&Xb0t(0tmts+oWmoXLbHLx~B zXi698&Y#A1FqJ>X#^>={yQ_;!FG#(&x%X-XEmF)D9TKtxs{305lI!y=LInR$c-Cz* OI=A6-8+mJE?S23SK9g_& literal 0 HcmV?d00001 diff --git a/tests/resources/namespace.git/logs/refs/heads/four b/tests/resources/namespace.git/logs/refs/heads/four new file mode 100644 index 0000000000000000000000000000000000000000..2abf339ac0e21c3f6f8dba69e89b8645644d8dc9 GIT binary patch literal 325 zcmbWxO$q`r3WJ4@)B}iFz3>+AL;USPF^Z;` ztPak4^ohOEUIL@#oTU>jA?v}yNgkmIT*g{%b%ITrKWUfV#rIpsTDCyO5D_wZSfN5( z3@uD??BUQ-n3F(mwZQqbKQ4dXN2R(hzbKl;1ks(!V%RxJDrh@6ijkO{`wL3^g}(UZ KI`@$4y)B={E?tBG literal 0 HcmV?d00001 diff --git a/tests/resources/namespace.git/logs/refs/heads/main b/tests/resources/namespace.git/logs/refs/heads/main new file mode 100644 index 0000000000000000000000000000000000000000..04de95a4985a7f86511838ef3cd748ddd7b21378 GIT binary patch literal 342 zcmbV`O=`n15QW$ADQ1~K6GpQ2XG-X%kOTArBh45KYztx)Uq2!3CcBWgdhdIi5An4? zkT{TyoC3EVonakVTOz}Q4^gGTwkB#D;F~wPGW?8XUdsZXQvceQJdXc$N@YHSvQ{aD zXgnOTL)_izoGa|}l53{v(8EQhseHgzt`nb{mo1zKkwbRLn4mcZjig1POVS4ABX`MD Xr_Ecs_F1=wE!PobspIdOX`P!J-x_7W literal 0 HcmV?d00001 diff --git a/tests/resources/namespace.git/logs/refs/heads/one b/tests/resources/namespace.git/logs/refs/heads/one new file mode 100644 index 0000000000000000000000000000000000000000..bd3c5fa25b7bfe8eac419b3e0d6927fbebcaad75 GIT binary patch literal 167 zcma)xK@P$&3@{{?zR6B?rz zJ@|kja&Qt%89k?Dor!6Zn}>_d`ZT!SYkAcPjX Rxxpq+xn+H92OwbR)^F@gEvEng literal 0 HcmV?d00001 diff --git a/tests/resources/namespace.git/objects/04/433ff5b52d6ad534fd6288de4a57b81cc12188 b/tests/resources/namespace.git/objects/04/433ff5b52d6ad534fd6288de4a57b81cc12188 new file mode 100644 index 0000000000000000000000000000000000000000..be49bee0e6040ca0bfb3d840be3a38a9d56994a9 GIT binary patch literal 160 zcmV;R0AK%j0i}*X4#F@D1Ucsw`2fgH>ZFzs;=&L3KpHzLhY}Q0@qG&72i$gNq}ArS zEVpi*=Us2AmbDA-yB!<|Vb(}#j0~)f1F<9r z(Ul@zNK&CGnzZ)0HhYm*YGSW*U7q!BkGj!MI_p>b+9B8FWHAIp1c%P9XD~D{Ff%bx$Vkn}$=55XC}H>>y&&F%Cy*^>-=c?q_doq7 MEaEdA08&R0S}ze5g#Z8m literal 0 HcmV?d00001 diff --git a/tests/resources/namespace.git/objects/10/fcb1c85bd6b3bc6f43e0a3932ff5859121a84e b/tests/resources/namespace.git/objects/10/fcb1c85bd6b3bc6f43e0a3932ff5859121a84e new file mode 100644 index 0000000000000000000000000000000000000000..3005ed15a1cd161a1c024bfcb8a973f3694ff74f GIT binary patch literal 54 zcmV-60LlM&0V^p=O;s>9XD~D{Ff%bx$Vkn}$=55XC}CLN_+;qipn(&hiz%c1X3HwCQ_e3_u8a4-P3Ub1I199USBlcz_*!iGLs1< z=cNH@Jhhq<(BORxY(0@;W~J;9N2?@Fqr#x=;HXn%@#31+1}^!DO|Q79ERH&oi)5H} zoUHRQOh#!>#tGirTq-=`!8O8jE_o{}TvMkXbx+^m=Pse-8%SfMl!(T{83#nsX+PW2 WpEKfE+6?{uyl)F{S-b&v2vVoZc2F(= literal 0 HcmV?d00001 diff --git a/tests/resources/namespace.git/objects/85/10665149157c2bc901848c3e0b746954e9cbd9 b/tests/resources/namespace.git/objects/85/10665149157c2bc901848c3e0b746954e9cbd9 new file mode 100644 index 0000000000000000000000000000000000000000..2f2fef743dfa7bbd3a7a34714e3e185e45911c82 GIT binary patch literal 20 bcmb`A9X-2PSJ?3njnQ0{NCRYB{7O8Mao39COiF*M=zN1Y|7{AsPn7G-EI{FfcPQQ7~i(Q(OJvyI#cgg~4XsOKZ0rD?aeB5GrZJ z@Llr#6@#nV=TC%XId6KM8rE^S114$ApnX4m^~U5S|2JL#{Go$q{!_M|=S@(ZCJe0t bX@Q=iHQFZ`TYBucOEN=Vp1uhHLFhAm!lpO` literal 0 HcmV?d00001 diff --git a/tests/resources/namespace.git/objects/af/5626b4a114abcb82d63db7c8082c3c4756e51b b/tests/resources/namespace.git/objects/af/5626b4a114abcb82d63db7c8082c3c4756e51b new file mode 100644 index 0000000000000000000000000000000000000000..822bc151862ec3763cf2d3fa2372b93bbd3a4b65 GIT binary patch literal 30 mcmb;8XfG>A*zjTvR(eX VQFmz#Hv4I9b83Cg>J6inQq0m@RAc}E literal 0 HcmV?d00001 diff --git a/tests/resources/namespace.git/objects/ec/947e3dd7a7752d078f1ed0cfde7457b21fef58 b/tests/resources/namespace.git/objects/ec/947e3dd7a7752d078f1ed0cfde7457b21fef58 new file mode 100644 index 0000000000000000000000000000000000000000..a6e1d1d8ea8ab31ff0ab812ff88aee91a3b0a9aa GIT binary patch literal 54 zcmV-60LlM&0V^p=O;s>9XD~D{Ff%bx$Vkn}$=55XC}CJ1rnY6F$m-Kg*KD_+;Lx#g M4|^&N08n)hS3(jNrT_o{ literal 0 HcmV?d00001 diff --git a/tests/resources/namespace.git/objects/f7/19efd430d52bcfc8566a43b2eb655688d38871 b/tests/resources/namespace.git/objects/f7/19efd430d52bcfc8566a43b2eb655688d38871 new file mode 100644 index 0000000000000000000000000000000000000000..b2d51d93bbfbc7f6aa088167bc6218ce86581967 GIT binary patch literal 19 acmbJ+9&aDv%nJ$t literal 0 HcmV?d00001 diff --git a/tests/resources/packfile-sha256/pack-b4a043c0ec5e079e8ac67d823776d752efc71661592db317474a0cf292915f31.idx b/tests/resources/packfile-sha256/pack-b4a043c0ec5e079e8ac67d823776d752efc71661592db317474a0cf292915f31.idx new file mode 100644 index 0000000000000000000000000000000000000000..7aa472ceaeabd319cd129414f9d72cdefa6b15a9 GIT binary patch literal 1376 zcmexg;-AdGz`z8=ga9K@!BD~=KT!)a1ILfD5l z=wib$S;lix6Ym{;7xCfrv-qo1jMuGTUOlNY)zkj^q9q2ulQ&KIk+I(I+nJMxU#RAp zb3~pC?^15AIuUICHR-GA^~l&*zPMoS*w-c@I@3JmUm0)-OE70A1ha+oY*PJ^6zBZ& zfxn8TeEHdZK82ePE#AOjpWry#?m`x8Z&^QqeU|I*td8~HV4`n2+26M97n|9+kDb2(r97Xp literal 0 HcmV?d00001 diff --git a/tests/resources/packfile-sha256/pack-b4a043c0ec5e079e8ac67d823776d752efc71661592db317474a0cf292915f31.pack b/tests/resources/packfile-sha256/pack-b4a043c0ec5e079e8ac67d823776d752efc71661592db317474a0cf292915f31.pack new file mode 100644 index 0000000000000000000000000000000000000000..adbe70ad35af897528d8ad69f89907a4479859b7 GIT binary patch literal 1406 zcmV-^1%didK|@Ob00062000NENqC%vQ^8K-Fc7`(SIlu2Wr4EVQ%?a=hy-nwq(VKq z@q~RYvW#doWtZsXp{wy znnLun8zYxRP*$Hg553dWPC~+Gqt)mkb_fxDAHcQg=VrNq8?@+^f%UjE)W97zXai>O zj6RUFaFGdz3NT1P=upFMO6Y~?sSbKz;kb#43^`?hUR{lKniVK@$wW`48NayeJ+$R^DJ_7ppC z4E8X1_vlq0UMII&s6TkjVgmjPcB6Pd@jj%okqg0d9oa`-p6ipek+C18oC18W#fMKl z5QYzg0ki`(3}zDhUe)sTfK3c@XnF1UqWZz`{`hX<<~+S{q%=^Ip!^nJuFW8Jx?O6Sf!?OQM>bqI`xaQ6c;+%>S$2}PXyW~YXnhdy7 zI39}ncD1P?UvA+cFUx#cZ|85`;xoQd5f4br%(3&z#);<<^!;^tb<2?avbZbiEwCAj zqF!EC6)aXICLG5`C5h$4f%Pg3_iR;7aNYrGMPeNUp7z(FN{jPz zQyDmHw7Xrx94;003Yd*??mr7E>V z5)~;^x3yH7l0Q(4DkpCCJnb3Z+ppT=EbTT;UUL-{P_xFLXygjdbdwe}*&X zb#s=yt>K~EhHb8QIa7jHc!#%LUJmyknq46VDn=Iwb_V9fdrT{1w}C)MvqH3xhvV*P zp0TILZ4Vh;aG?jgr0pXC-KP-)W)}ndp{6BGai$|=z|hkSF60!=(vbnZ{)#^__Tl(k$LurGKXdtS;Hc$`&F+fKwF5Pjz>=3TdGp%=Q@7>&=y2iFgn(t%=HXec$? zzn8kZiIPb;Gt9Z*yDw4^kYg!w-PNMwZK-7~QJ17^rBtf~NnX_?np{?`qN4Z#KpRPuHacpXq|rJW`e>Pf&2)$fD$J z0}pvRjGYI&K&m(p?2`T(Rr>&eM#6>eE;nOX)@j19?Nox!_ZxWqOTWEOv@B@oG4(E@ zb=DcsYe*Xb=rWJ!Fk0`}jWw@f_Q~ZgGN3b*BDolRzbfjX+y2OBjD1++s6Tjp=(Z!g zz$cuC6!(N{O!vPJvmeaAd%ZGvoJ-^a007PaY_y<5!0cWJo{GkOf;V>8Qt!tWVOcG+ M7e`7A@{*BXG4>I-djJ3c literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/FETCH_HEAD b/tests/resources/testrepo_256.git/FETCH_HEAD new file mode 100644 index 0000000000000000000000000000000000000000..4562d90261c36acf4bccac612e949cf0c4653d9e GIT binary patch literal 255 zcma*hJ9Yvw3_#I(vWn@bU}RhJC%e(;13AfHj&Z^ALz6z`d(~AFc27W|<*LCGM>W@^ z$Q8sCQh-227F=r!X-|X*F$r-Pr<#%b-oUcct&w%Lo1$B$j4AKUwE z)1GtKqhH?fQLJG^feaLdQ`%jqwOxeOECXcHnlo}^FBvNbBnkk6UP`ne%e~LD_i;XK QTy0(d6gOu1HvKQ-7db;u4*&oF literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/HEAD b/tests/resources/testrepo_256.git/HEAD new file mode 100644 index 0000000000000000000000000000000000000000..cb089cd89a7d7686d284d8761201649346b5aa1c GIT binary patch literal 23 ecmXR)O|w!cN=+-)&qz&7Db~+TEG|hc;sO9;xClW2 literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/HEAD_TRACKER b/tests/resources/testrepo_256.git/HEAD_TRACKER new file mode 100644 index 0000000000000000000000000000000000000000..40d876b4c67875988b065073903902d9f84ab634 GIT binary patch literal 10 RcmXR)O|w$)aCLOy0ss+W0<-`C literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/config b/tests/resources/testrepo_256.git/config new file mode 100644 index 0000000000000000000000000000000000000000..c1aac4a0392f04cd7f87fd4ee110a205c76d5df5 GIT binary patch literal 147 zcmYj~F%H5o5Cm)c75M^4(9z}zG!}(pmT(CBthL K`pn1EIeq}h#WI=z literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/description b/tests/resources/testrepo_256.git/description new file mode 100644 index 0000000000000000000000000000000000000000..498b267a8c7812490d6479839c5577eaaec79d62 GIT binary patch literal 73 zcmWH|%S+5nO;IRHEyyp$t+PQ$;d2LNXyJgRZve!Elw`VEGWs$&r??@ Q$yWgB0LrH#Y0~2Y0PnOK(EtDd literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/hooks/applypatch-msg.sample b/tests/resources/testrepo_256.git/hooks/applypatch-msg.sample new file mode 100755 index 0000000000000000000000000000000000000000..a5d7b84a673458d14d9aab082183a1968c2c7492 GIT binary patch literal 478 zcmY+AT}}fr420iv3X@h92(lHgNJwx8E|6}$o2dCy?4>P;yW@1*QeN%xH{)5{tv5cc z$*F}}z)7L+`NP0Xu{~$LJYC9w8!;9TC{>Fu~?11Y1ft7R$YZ zq2>ryh$dPeF5>QF^dX?x!R0Az#Z{1d&kj;f<_l{EV#^bO9T+QkqRFRGaI;6vrFzSF zp@JWv5o}^=afx%eN!tNj9X&Nf2zig&CdI8B-aK}BYVZNiVMUbeMoMAl>6H5ks*K`! z(xeTg|GqboM%^jZ!RXnLGlV=9HJ2y5SG~NKjbJ`av6T>vX-cWiog8RAYa8f6D@I~4 b2hhtaLc?k$#bN({xcq*8)XO*hqh8c6SRA2` literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/hooks/commit-msg.sample b/tests/resources/testrepo_256.git/hooks/commit-msg.sample new file mode 100755 index 0000000000000000000000000000000000000000..b58d1184a9d43a39c0d95f32453efc78581877d6 GIT binary patch literal 896 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 G75@hBQ{SQh literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/hooks/post-update.sample b/tests/resources/testrepo_256.git/hooks/post-update.sample new file mode 100755 index 0000000000000000000000000000000000000000..ec17ec1939b7c3e86b7cb6c0c4de6b0818a7e75e GIT binary patch literal 189 zcmXZVQ4)eM3aSIX8U>eDH)va{Q{!SnExfa+L4^re{E# literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/hooks/pre-applypatch.sample b/tests/resources/testrepo_256.git/hooks/pre-applypatch.sample new file mode 100755 index 0000000000000000000000000000000000000000..4142082bcb939bbc17985a69ba748491ac6b62a5 GIT binary patch literal 424 zcmY+ATTTNp3`PI5ic31GK#*4aRziY3uz}3f(?rZ9QS9jh#NP4r0pj=CI>*O?q=*Kb;Le3xHuErvej6K!ZpKu6X5E;JB(>ZSmT^`3MLR$s2C-_o^Q}NOT z^fiz0%5DXohWASimyy?Zr;=vgtLLyGwibbV2uz9+!40WyeLazrEj4 za*7Olv&G}xci;Vv$8Rpz&R@o+I4+K9>4~3B*SAcK$P>jXxIR%5+H!F9o_38%ZUKX(=(x2AGjQE&gMnoYSNAZZ_D0<$W)e-DZk$>f2G??%iBvo zv@N~6J-sea))z-+W1Np^p&@WgfEaxlhv*x{n8>8XP7hk)KgX&S(k)U-zCC)SEV24pvw z1&vZLBP?aZfiLK-OJ`A&X#eQ%>j10m1;Ih;C7=V>I>kungS41zr0c7*NS8wldF4|$ zzo6)Rm6=p0;@80hJ_x`LC(zMg(@+3uYV<=6KM`spE-jsXqVnG_pRdm7JMAhe zt8=ySYTB*}LwW!H^WC4n6?Y*>xS=K9A#6{E#;SL(fhSdhU4B&DE38^&)O7#{?7N5; zZ+>wR+L@+r}FF}N7mbL^#n=~a8neNU!!Rm^%48e0_F`a)S9FGtX}_o7PJG-)pm`; z*fP@CN(u2|#6Qni>KbILoctn=kA?DH8`n-7tglg?sPmSeFkz`fHu3Nnc!ml1ozn|fkb>!_Tvp#X9b>NySU!(9iflQ;zekv)#267GY#l&C?+ph zC{I-2>ct^M*gUNZ1>qWK-Cu}{>pUn+n-YgKRNs^%SgfoXHwtCV<<*A?Ho&HoW6ItN zX$G^MNL#80%RpJBBX%#VQG0uqm>?Q>?{hTPx(c)r6l|x9#p$qp_7k$6mg6$|{V$?O znW{Tq{VpzQV`}Kiie1GdYcfJCs5TUj=S%zXc6o1hKW=vPfN(k)9FI2Y|I?ah^8<+F Bir@eM literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/hooks/pre-push.sample b/tests/resources/testrepo_256.git/hooks/pre-push.sample new file mode 100755 index 0000000000000000000000000000000000000000..4ce688d32b7532862767345f2b991ae856f7d4a8 GIT binary patch literal 1374 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 Y;smb>eoUSY1_no%47tB{mPBd92U6On$N&HU literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/hooks/prepare-commit-msg.sample b/tests/resources/testrepo_256.git/hooks/prepare-commit-msg.sample new file mode 100755 index 0000000000000000000000000000000000000000..10fa14c5ab0134436e2ae435138bf921eb477c60 GIT binary patch literal 1492 zcmai!Ur*aG6vdy{PjN{r%AY0~+uKklF~(S>F(%r*A;3*;8jsY@YzGG7!|ymwDPw4p z`jFbb_n!N^$L?>WbE#5W_WHd(9Vp^oVp&&ArPkMEGb3w9PE&2T7KX`{OqpITrK3tO zXvx-!1t*9-6jjAJ&F?5$U^g6!=vKP2jZ$LCq>J{ukf`8F;iweWuOPn5+GQM3p{q*Y zhK#;y&OwdTYLzC0Ahrt{TC%z^87D+Dg!mq?RyU^BmPw+NCeER5-NrhayedRag2om= zA!KDk4}z3d@jV+&)(O|x5kl8_e0DL{#&HfB*qWh~67#lE?D=#fGFSozS7IeV&=hrS zi8b3Klxn`?|-d8n;fy6N?L!&m~zx~+=TXNoI zkj}2#0dSMAxRJIy-5By(=zBmS{=ToavmHLzip=*jJ^e5qZ25vW!q73GhpuNwXP1+YM_*_306Rl~ zqM=PM&bN}C_vhQm&LI860PpC0FRh2ZVV?`w+2Cfn*cm(mY%DsEDh8H}@!72cB!Pm_I literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/hooks/push-to-checkout.sample b/tests/resources/testrepo_256.git/hooks/push-to-checkout.sample new file mode 100755 index 0000000000000000000000000000000000000000..af5a0c0018b5e9c04b56ac52f21b4d28f48d99ea GIT binary patch literal 2783 zcmai0U2hvV5PXh)#YQn&yYR_y9+M_TlDbG9`hnI(+b4m#Tj^Nekyn05QH%cf&Mqlg zF^uNP)*U(AotYipv!_=p>#kxyn?0j9j`*V)r-7;W{*GcB?35^Z%2Q_&lcBcf_Kv&8 zXFLzgsrz%AP?H!~Rm&Dp=}ScLO8^%ZgdcmshJ`T-#IX zO(K-n<^a?*><^uhbS4L5F(7Kai;ms?U0M6KAhh1C?Is74EI8PjV9g4|0W-32hRx;J z4=yG)UE${Ko;qHeJfusC8HJeADz>4+9Kn=b%h|N^;m*2EVYwEB#ykE9WM9?<9zA5a z=Ye_?Q9TZ^>&h3cgC7;~*ed|4j@oVO$I+&jMT?bB!p{GlPoqg~4-i>aL8*XT%CkM0 zz_oes=*xOt?RW>OMO-wR>~!Bs(Pir`YnfGJ65F1A^=w0o2~UZyoBj? zj76m|kCiJP{0{tBG4%+cVFwglH{Wjsj1WgLnUI9_$y=9b?E@NfTXq(EY4o7gwyOBS z>UC7APYQhDf_4^E?s}_sL)CUV=vGOS;)|Ie{{|;Q?b5N1TlZpCkY1f#%XofB)EXI4 z%!^_ha^5w6bMR7l%IfuEBW+WM==?BZo#zOY=r3j9#vBv2*QWNmUfo6L`Jw(7i&y*$FGK<3BfsPuA zYVHzj(qa@-?I~oZ`G*AS8jZvzQ!~>0n>XKrqU*VK1XepSrY9crAjL~&t{H=b4oVgY z5|T|y3}WL5qoUhZ0tO%|`5|c$c*SdJ=gX<^>L~t_6%T8%B0OY(iLDt>w44#m2#H`k zY={6yCFoUtX*g)YOJ(JqdZ)M*8p74cx;y5nDnx^C&2ZGXw(&`ZX`7woqSy}O#X%yf z^d$wIWY&t)j;pwbLl@$(TdXTXjgc{!$iR&c&4A`ardDnx<02TAR0iEhnqfH1-8<;s ziN$2F^~jRN_d%dVMQ>sb6IkKU5BBH}ONokQpAY{mv$uB#e2EWIMtg}T9J7Ck=vYb$}zi7BEEP+F1Ey)#c zI(bI(wxh*jE`G{U9t0Le05zG^M<|KPo~qZ%Y&K=)o4=@O?8b?zF|Uxf8Oq`rLM<>p zQoxj(J&`P$|2l~{`dOk1(b~Y1-F&vTC-CB_W{nqu@>jOFnjb&m6#BP%^&XklYc=B@ zHyemjgRGoXKX=rP!RHOe`NV*J{X##9huxezG-9OpuAbKH^+FLRwYiNLp(^bN48FXL2Cke4fL{7(80xVQS6K%Jnxt Y#eL`V&}o9ykGfOiic=-sl~(ELKPd>gcmMzZ literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/hooks/update.sample b/tests/resources/testrepo_256.git/hooks/update.sample new file mode 100755 index 0000000000000000000000000000000000000000..c4d426bc6ee9430ee7813263ce6d5da7ec78c3c6 GIT binary patch literal 3650 zcmb_fU2oeq6n(aS#jR|_wPD#w_OyHrU4jjL7%*(fQ&9x8Oj%rH(i7>p>e~O_LsGJ7 zIdhVAL4YVC@AtXqUUlD0rb1419(AKGy_3X0vBk3Blq>Z>IxWT0kWn-(RQfAIL#zm zaMC$DNmMcO50bB)Gq(zw*%ZE*TxjRe2qI3xy~%_;?wfPBrnel=fjx;{wiMxmN`i$?p@m)?V)J$a6^G+~poffRJ zDR4ppIbazoPie`S5lW7O$X!eTz`@w3C6g(Tcd!tf@cnI$675yuzouZuW#zo*FLI^i z3uSmw)e)m4dphLs2+uS%@ zmMiNg9I2b#wX}6S4cr*Vbaiyv2+~_9uhfdxOq!8F1!sZT$W)L|IzTG`wUZf%v7({KTKBuC6f5!{-@^kWm&$wMn zZ`k5R(wo}@3s8qj%2Y{Gfge5Ez#7rARDbc**jG@iK`RNT{>k6{Ep#Wr{df?iOmiFt zf-&egitnTy4zr-;;vs#Z7$P;~hr=QL?(Ky>kQ*gA)1Iign+3bD=$xNNT(h+4wQJjC zWNWVx9QvW>;b&X=7(e6j*!~%jFnu(+>n5NEGsD*vuK?(A^qH5c&L-^ViJIDE09M+} zgrp0E{y32<%$_e~O6q?&PJU!b_OVa>P zWtY8w>ZfjZtK%!KIRcA&?e>f54WcyViU&bI8WE zzx?$ZS3BRP#OH)9>c;0yCv63u2ytI7gsc~MeXK35-&Lfc@2q#S!b*k!EmLFL(sq?9 z@$C`5|HaX0GuQPa8G^tM#h R8hpP9DRhn<*Kyf#^bN_-i$eea literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/index b/tests/resources/testrepo_256.git/index new file mode 100644 index 0000000000000000000000000000000000000000..838e73883bae7a33e15607de712e2771ac91b236 GIT binary patch literal 11148 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 literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/info/exclude b/tests/resources/testrepo_256.git/info/exclude new file mode 100644 index 0000000000000000000000000000000000000000..a5196d1be8fb59edf8062bef36d3a602e0812139 GIT binary patch literal 240 zcmXYqK?=e!6h!x)VxWtv*mf_t5?px$aS_{}Hj?C*}5G57oswR(_az`n?hi429u!=M=s`8_BX_WhkYzN9YMGTTV<#0#4@s9ZC;Sn74YXA3lJ`<|aS} z&P2?NqGrS)a^^zSlctQNSQ$msYat9dlh;_0qai@_!F|}~zRsR*>R$EuJ@0cnmz%!i zeSLFyPYaAAhEY?cML5@r;B@k_=!)4CsRfJ85m*YK2JM^^T}w^V)FX18zc~MeGO(Sksqbf@kRao*`h-K%(-+bQe@dt2V BL^l8c literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/logs/refs/remotes/test/master b/tests/resources/testrepo_256.git/logs/refs/remotes/test/master new file mode 100644 index 0000000000000000000000000000000000000000..42bdaa27fc119c3682d597cd19a0ea4377fccbf8 GIT binary patch literal 388 zcmbu4J5EF~3`J{LMK%Dk<4+t3A;cC~K^(^n1w%+6)~w}e~xt= zx8G;pj&+^h^ZLGizt8*l4g2!_e$V&y9@g(U{670}Ex+Y^kJI{oy}$eYn}_KdfA_Ji z+x^~$;kTXl@7{*(?X#zC{m#eV`#tXWGJN*;vYzL>eujHJ&hztGujQDw@3;)#Yq^*E zd!NTTEXU`*r`zw3+p-M9`kJoq`o8yZ9EWS0j$xShdHT%j_qTkebNmd`xEC<2bi{o|pX`&Sm`E-|uhSwrv{L<996g`}2M6>u}A# z>HS{z;eGCtb@+^*-#Sg}y}q|`Uq0{m`QBXVJKo3lxX)`HJl*G9f7do!qOt3Y@8ep} zb=jux$11JcZ$Fpy7`Jm;?scB`*ZX~RSD)YM4~FyH*4vsdKhJgk-p8<1fFu4}ue&-S_ZdE2k!@N%!u=hc!7!!n-7 zcRW9SX>_;md$N4gx#JGjz5+?I0NUFw?m`(7tEyT14PyS(@J^u9mWIS=P= zd~fq$A;)vICfoV-i_7md&c}3&^CGb3`<#yVce?!Yef-Ytx4geT{WI;``1c-$X%h%P zZ{O=5Cl~mAw`&uH{%YRNW&RA?v3#$49jEv3*?!x6ypQR(iLL21PhQe>4+3H@(thvZ zyl2nlp66+w#$g$z`~6(WYVV%X$9%kj`TTz8>s*KNoIjuUH9pa?eYa`;tfN2L77=#e z+e|S&+mATpKHFZ3o z6A{Ba4cpI?Zqx7dx9fUN;%nZA-~Ijx{@?sPk7d7)PfJq5OxJW?+jkv4=jE9uq4t$p zpL<(>(=spjHp}|!{_MlLpW`uquB+AC&`2IeAf8V{f;gTNW zb{YKrIt;Smls-TI|NR<<)B8Bq?|a_A^KZGwV;W?^df!q*#n`rMnb*mc&PfK{E;8+d z{~k6m^P8{V=)*tzQVsd|jQw=a=cOF{&RGFiwsl|E{dIm%KXsh*yA3kouax=*)UUDQX5INaaMz1`RE zb?XS@_}=&Ts_bl^Q*9X5pBz=J=kMpE^m!}2r}>p(KO1UuB4O*&1*g{U1{1h;q~~4Oua*OIj!q(?EXbu{?19&-z~xXRkcOY>mIGg zg>)e;C0&scG^V|o2^jY=8<5*p3v#{S@>!NtP7ZqmP*Xj5EjcTjj_&wM6TQ$B` zKYvJ{<1=4ESI@q_%WGP7ecjjJEXw}&)}6mURdf98(=dFu^Q{QqA6HWJt(eBV3AFjA zpG>kzR;}Ko^jP%J_2*(j*vAh3`s)vmX*!m9cnN+bZ}aS+gcosqCy{!4W>?(~Ri%$O z)CfPP)Eu|0S@-w;+qd@#mdK=Y9_MTGc%OR~)5q6>UFYauPVa323uO0eAE)p7g$>sC zBA%90ch)V{>DkihM;~3x9XwY$_w_!G`<{1g$s(Nc=5mGgbLooS?HHNTb-JoC!0dpXwkM-@Njd-BniVjTx7DM6m@KIs7S z8&24Cgt_~J(9T=rxm!*0`+c9sFv5C1=ln?URjX1<)mbg%HEF*42rgcmN7n0)?{HcE zN_sf!9;RI>S0lV=&kl)PuHxo)zw$Z9^-ypI8F#L$H}_lD8I%H>pu0-;G)vyfUMh$NaLhOWYL782S=oaVU6TFUlSx#5d&flYiodZ$2s0Qm1 z1dn>Ze!uG9PtWo^?`hNxK0}>o0+4>t^!-|=O?UQMyzu*yocHJbm9(0!*K>VkiA;(HcqwKzmaXD5yRG{P zOb}MrS9Rc0zpX6(y+4C1dIqtwC}ALwItkT70)ut9lx3iQke{mf0)KoL`?=j%n(bFuSeP{_%g~EQ^tpU9du!8s+Sn zzVFZHw`f~mIpogV`=wQQM9+3yn*tZERPi9d@q=B-yZ2ko2dBrEkhF;Cj|6;c^lydE zYHTi}@fBWUS=Q?PDi6O~s=;^TttlMd0dgee2UI{+Q=%@F7)?5|W^L-+i{@3sK`@-_CH%{}FCf9GjgEHIlw9TQIRt9E81A}<~x)Pjv zTES&dX2$PfjlB31gwl-_%-y>mMwCSl6WFz&xk@F!A+{HixWg_$b^&L>hw#}gS$>fl z;6+aD)$;FKY{?9vC*=XT;~IVoR0ei0Ud!(0b_5_Md|^Y^VYxr6)!cq^lEz!vR()52O+r9_?;EJZ2;b?+0cus;~H?}2on#BG6`TH9~Z13;KCQb z4={IM*ZB%Of96p~M`Plyzwy+3fIVn_+>xX>Qn>sp2^XLOu<$alLk(1q*i@|BZz$4$ zh5Dq>e1wSPJfLiWrZ=ipugi*JRi7viXtM4g%UjI`4I!cmKBgtzU1Oh758q$_-+->wC!F@wwjKg%tFZkml>B z(s-(=dx0#hb#(%z0Jd?y=+OC-E3UMCAb*NRQTUa@0$EZ0#ci}#G3>V?-f=vTOHsLx zw@8Fx1~SF`n$hd~T9;WigK{J0I2|*fVTDACP=U_q3SCM0dek6gOC3hzEhM<8o1Kyy zepCj5WX0s1_g^B7Kb_Pjd`N}$=QB1B(TbdPS(JRl8s6CT4`yia_PXq^Up8C5>*-PS# z1cW~z1MSf4@DypJUgC`)>rJ}y&+Aj1;)H8pSe zgO1+TgPNnQl0Oo|TnT+4x13)uf|_&O7lNt+zzNglcGcz!Y{Q^{SH1PUD_tRu8>>0L zFP|!<&_|T zw-zF3(GPd8MNA`biRXe&h!UzvsCX+Q$5&u~yd+6NwmJ6iG#p=CL$bnZqZT`o@E(+T zMVx0?MpsnPb?(J)4OlLYVlllUX>olI8YF#>sHXRQP8ImkJSa9R5+@%8U&tB@*r;yu z9fvzM8i9^(k$c6ePLlo~sFRasN!eN>{0=i!~9`K|B9vI}LD}G<&L^c39 z&=6TPQJ`j_q%|$bn9xGS@9Ef8SoKG(#X+X8qWxXI^jNx-q>`AWA$9h?CTz|a=h zoTbHU#7i=nfYj;ZEKrKPdwtL}=skFNsV4zhu>#&EW4H&6-F?lyCuHX!PdxvsBB|&L z;uamd=||e({T;y+fq-e?dypNjK_(qe0^DnXQc)LCV>PsXsiyz{Y9TlJoWI#e0N_vm zb{W^3PmRr=X&RBo8+MLVVL^a1+3idST4aZalkLmp#y@y24&H^V$L?*UI3q>~7hnuv zmKI0`8Nih^RN^O2b_;B3R*1yEszC2FMIA#2CPLDDdWYgarm~4{%zJowUXm8kdpJ}B zk>R0~k`;FfL;yi6&E@Dy(?AE>l?LEfqAMC&6fHU~uZ)nz28G9hTiE@g0w5VUY2qe@ z=tU01nK6^4yg+=uY8RY+i)aN|_1+1wmue)gHP;)~9B8)HQUw*xcTqIly?W#7hDY)5 zLK&ojK|iBUz+bPI2Og-i33e1KoePE|4#UQqjs@T!8X7UYE2(84a;AGE6>b~t;X)E{ zNOyGz>{ANr`ko0OfwnH4S4ptw>-~L6f8^rw=5Tb1nnXl+kKuQ@J%IC&DiCg~=Pgyc zmDLYX39T4zSbhdTki?TR=029Y9xJ6KE^!S~I}Wh>drmJ+OAVh;YJ`qLC3zL+WroTY z2*DAX<(1_t(91kF|COPiq({H-=FDRg4Z5~NF0%r3GUWh-x0g37( zREAv)4D^tV&`R0Gr&XEPTf6y)@J2%V;5qL4z37hs>q^qGLBLxksgGZv zGl5uo4rFma2i^cZbz@@|fLe@|j@}LN^KIGyx-SR(Z!9IwtV4pSWYWfkDds{ny;N8T zZo9SEAz8Me5ji%sq_>1?4jLV36p98iAaX@OT0>Km0mbVz5eK{-pNbwtUX{T$3_zfKP)naHQVHqXsiV>K$Om&`xArW?KS~&A@UhOiR)MOyT(5)@td71( zIHJfTbZI+cmV|`j$qnlM4Y4Gncsx3i)`ryS>Az7@;w(u0P81{6sKz{!w!-A&mb-Q)Tx-^>}sP3YG8?n#@p<@`BaC{9(pb8i1HY5EQNUFU&zV zqJUcfVDNGf*APR}LdohEshc+Nx<6P@N<7R1OqxN%0-6YAL;h&%mnrHwVrnF@nk%hR zBAo$Oi|jWpuh|2^LQo_nUE7n$C^DcTe+7`bwV!bf&`)&3HH1^0!L$;R8mBpkx*02P zrJ^e#U^<}YA$r6ybpXNv4^M+FvQ6aPr+hGP`(QqR5ujTzJ-f9wZ! z#-2!=-h9F@@aK88btVsprIw?dD^U= zU;&|1IEhn7&tf95Wy4Uk=p0`Iy+tPk8_dmawN+QC^g#+u)=u5-(ztg@mHGMl@oHvy zOvREc!1g#4(dBG3MS&(?ubxp~MA7lWB~|Z!{y+V9lQ@ELe-`O*w+^P)|xO1B1RM5ll~w ziDJ~SvlqXkad09gBTmS^?n7}j1yD3#BodB}r?WsI)E@5|vU^Y{g-SOeEy;eJRqpxC z_rbkV#*gw5pbG-IQh@@PhM@L~OiX=}x}dCxXpl*;DnKlq*fx&wUz9XLl1fS)C4o}V zP)I!x*M~7-IyBj@2oIIx=v zPeQR?0Q&nwp`vlfm<9yb3QC&KN;oA+3-PLDyTy4{kBj9O_w|yhkcOBy5T)U$f=Djo z#EJZ=6Uo`KUlcc3v?P7%3tE3n0v;d6!BHcvCKyWl=lCh8U^K)}p(0JJw3xa2dayr9 zY?CP9>y|jDVNF=6n>AS{o-P)ESHzT-yUOb@0|4HYRvq1Y4cX(Z|7YfqJ*W(v6U{~W z4%$pwHdTkm0le@Q*hdWF=^BNDzXXpPr^Q$ZWlDKtaVeQP z@N@F-8?~@#J&i^A#TSrO%73Yfj%( zVYTY%d9+)25ojDap_bntaLr$+$rDwVu)jd7qrx58kWJ#lV8VaPyCiUN+L64Kf zc&=H$WG0(nSVDxlsfxXamteq?Vs6G~#Ag!$9UO4A_Gx~`PrASaSr!I_4tnzmect46 zC0>t!{@s$&Z%j+ht|lr6{!f9ud4n`aN{a5TV;az2)=X`bN_uwh$RMwny16w50V4L; z9xM}iA1iHWfgV1uaicg=B`F93URzbd(cw*BLhCj!(`@>p8#Unr=YPZ`HP;jZB{*jP zMc_!DmijtoDz?|UK2RF&7QpfptHDgXQ^+1b8PH-cPNGAO)fH#}*4u>}ME7EDV{<@p zN?Btbxagf1v~2Gg3k zh2RP!H5rcSDu&xpKlK6E8hEJakGq+Nq)n41HLFGng$UPP3D@Ygk+>`A@7?^g!p?k5nfKYlDKIrlo zz{#g1KoB%CnmPq#V38T52*yGcUWHg-6s^t!6Z&9^)2JrdipN(f6O;6wJE8(S5*SR= zv^bqk8UKE5J>UiQXW6iwxH`7{;cCYaIEq$W!?5?#&9uqQGw8U;5RgiKhC*e2fVeTWs! zA&Z&%`2xLQ{l{i_)0|;QAx@WjPM~1R>h!x@b9JZTewE|LO?d+ zjhG0wBtS4J15fIsE0F=R0O{NG0@U5m*I*`9*y8gg3N&2}MghwZ9KuY>w2oxzcaJY< z8gnK*(;djg{+3LF^pt@Hk?6Eqr44tb3mI){2gYE(xe^&C4UNH)4dPNg8v#N%Fc|d_ z%FKW5jo|9ri^DC%;Kd>xvM&vl)7_|Ce_O^a>e)JLvYH7M2GFBmoLR-d z6Ht%YmFLqsXc)k;VXXda9yok4>JPl3Xox>}k(!)fh#i~y>-Ud;$-4GTu4F7>>Zs6! z1w^xoF@fj|U{Tcu%M=v!2SYLZlpfmeVU5jg`6EpKQf5@(#K1xYiq(s>QKUFmx7Xe? zQC}d8ZdiW~MRJxjIpGQP`WfER28f}UF{sw05z=nngl~NI7szJmG(M$AC8A^(8lxc03W7*-TbQUKcKy5iq~M3`pa2IY|Y zH@qT3RT#eMMm#-=2x3Pxd51njIYf}EkrHY_$erGE<)z8-WOz&2w|c_BOm&Ajp2`a9 zL?Vfy%LEEA%)R`}sPiBe2KimQ4H6+1FUf?|%Ws3h(3K8}2{MADswbV!q9QePX*#OR z0ouIttR@^U0t7&s<%u9rK6tUA0+og8snFpJ#xkBO?ZGd}8MQ?P)vjELm@YfG+0iJy z&FxcEEFwZ4#)G$kTMc&1&%`bazM-Cn8#jo=sJ}!tTB6tCRxA9Nh~|SnrAJ3d1K~YW zBe~p#p*w;y@W;`r_383FN3KJS;B+^~U5JO8xfqu$_=JK!+S{;v4FGwEj4}La^J4}h zLP-IjTN&lhx%DR*sHgpGO4xmv|Lt$pcDgS852(%nWZ{f)gWM7lfNrE^J&`LtS8b6= z@E(JzksWAYg(r4O25SF@*ckWaCYGMYz;2In1_5R@6>mD78smr6b!FA0fuWJv0xM!o zD4zC)!yG_6ExVs5qSpJ)2gt1)oK-%tlZOWJa zc550C7ep#ps085Q<6qEWpnhuTKnFLYmC$;jK{B_evIzY^$q*E#Z*X#w9{BH+s#j1( zdL(OA?%*87Pffuqt8zvk2&`A>N+)fGHl+Khz?rqA9XDRxkUn9jgWFeV%$lrSsG>Jc z0MuCA=8LzA0;wR`mZRqS7pbw5a;WB3Iqx=IfNvQJFg>fx%W31!BsIcuTOQCUmP8Zc zJfdQbEks2FXY&77-bkDj3d$_5MAGA}$jq^@(+0NZ zOJ8K&RBx_C{wT0ePqkd5`WPgig+nUMcnx^7xBQ5Ny|;IlZ2+{=Isr| zEHj1)$4|Q}vGS^?`Gvk&`Uz^Y@)mPKtE49eo8d`{=*CK|*(xF7;{nCS@8z|6PbFg3 zUveZ0#8j&7c#kBv-i#7*b|rQr00RDUb0!xmm7bH^&0-msk|ZEl#y?IiQS1R!LTZZF zXq{hq6+MIyuZHV1#9Zh!`iKWTPBuj7)0JG>e-V33gmfZXJNO!9n3o6n0x$YInZje( z?STo~O2#*eO6j-*pQQ~!u!9+&ipm`z&skK!xn?KkDT~~5ucF-V^7!OdKxqIqAEM?o z5ri{RNwt^5U3rO_0{pIh4m_;dKdsjEj#NMvvk;8oYMRz!Y(gPcoX8B%20lX7_-EM@ zz?CfM!5ofO0~Rs9HKO&qH7a66&yWLzwkxQFEvPR*al#lhPNn8!xH>}y#PnjLaZ^e~ z{Lo-Ar>^9QvT5*}=%Na)(Wt+rI)pxJkXFDnIO7Rq0VLaQ)6NwiOIvP9AG??5fY|e9 za)C)#`8r7*18JqjOwAqvBBy??I<=8YW??lTFtiVBHY`={@(}6f@}1Youq=x@I@Nx{ zY)L@Avdks#!-G3`oAAA}paMO5w19UdKf!Hk`e{^(s7vcc-pNmt1~AB$Bj_rphDJ?m zl7O<_)B~{{7AgU@f#1V2c#p?c^^C?ur~b;2CQLNg>K@@ARfPmF@9bO>l75P?C)lxY zFhm+a!_Y`$n@Nc3rqg;*{e4+pShk1ZSM>;{nM4|n-l9H9R%;LfY>(#d%3dQ@LNt#SZPP0?#jotNH z8f_?#ZUFaN?ytRY>E*m&eG!Npb;Z!0Yk zg!p(@H%ZNp8I_{iqQI?iViXW&qsTqg1qvx&K{V5<94|y*_Qg#noRre0yE@Ucd&ew+ z-QN&PA+jOH+o;Jm=W1!l(Bg|zkS`BlJB^2&7hTFtWrcs z0Kz>%lxt8vr3*J4}0a?FyCBOn3rB328ymB-n`>;%3uFokS67&j!9vXTxo{$=qE#t;l;l zFTXa$(A~#6zJvnWHE}RYMPmzBlKsyfY~0yo)RZ+*LIof)cphxa>tXOHVcjNS8xFC9 zL;M+(Q$EZr>{80XBO`o%d9Iw1_sN*8>~u;gND>wT$5X&POZk% zeg>lsNlL1viZ#-tZ7?RSFTYP>r`SXBo<#i@+k`Q1&jc84Mpu;i&6VQuM1K3Z^eRPv zlWt5D(h)S&rlq~C)yuVe#nEsLd{ui9Vd})I$qcbK`G!eX-eVhhKD>}LYW@VKs8vM- z@JB5q(mkUFCR{HLmWE(N1EzovaL(x&20ZP7r%4tAC{zQ-=7j&%a<7p_O9_+KQm|1b zJ(W?`!U{iE0tX3{z`B9C_JCNiSnxy$5eXnU&>^k>VW~YsUXY&t?mvtb-e&C$JB zgKr;a72<@a(mp^ETg*H(>`Vx>tn%io||99}qKMR#TPH9pYi?IHT8dkT!{B0xwi2}Ywj zWU`ur{j&HSsttA`^mfo2_(wCCj}HaKs0tsw7nDZ4}YrpWWyfMl$a+6r{eSwChjpqgJa>Z~`&HV=DxI zQf?(_%Oitx$_iJKhe1MG26pRp+9HBZ`)thnc|{%!Czl&|Q~qV-7v(ZU%d~DzNFj=! zwFl^#OyHNU=SKK|sWFfe0HT(InL~0bMl3P%6j|VRGgl@l@73!v*8t4zP||cbrA#pt zO0*a#uq#QPnA0e7nb?DPM6zZet(qr~9;?BD(T3|@*fk0~1V7G!GG-B}vH2G-|MAdBMlfuur zl}nK5!zs|FLa_|3kct&^#!lnDx7AbB(N|>AK#QdW1kU0OiNYXe&oY64w*p*Bjh?S7 znZjtNsH#$N!A3~1$foE>A+o<0%`}giOI5kyvxJMe1|5f7WA*^B3JF=q$75Lp4WkPJ z08N{gh30k6S|J0Y%HF9CqWtFZ^}lFIBnyp*oGOaRA6)*-ZBkb4)2QD1Q@Xr*w`JI5 z=Yjvoois2H1$@xZid`F#+SZ6FDho}V;C96hkA6X^MvWj8!eJMXb+!{wf|VNCoz%lz zc9aj(5Y?MNjK$y=RE&gl{G4GeoI+(#nK=!;9;#r*P1L6CL12#k?xbF26A>hi$VXX@ zc9rs)T^3^-e~4vs?+NpO9JzoR<3LGC0a~|_zOE0bKzY^ya?KMW&o#)BjPFLUO)sK4 zCnPsoo4EiS*{DF9l7?d-R(Mg=(Uui8|3eQ;#m5Ib4uSE&Fjxo_QU)EIJY)-uTiB5i zq!?cdMQMdw zly^9ZTzKlU5M$6E=Hf3hWyf1iEb1p& z75~FD4K>fpsfP!r6JXpy+pytnePK+5zzziYXbtIMD5tSl8$W@Chn#6>PWIy7gLX5 zjPKi(gi{5~!zC7^ni)Dhx|>!Aygz*ycF>oIW|TRN$0h+?vAOw62ZF*eSvqBBf*2%o z2r9AZ1DoS5=@UY|zLdZj;S z7q<9mFY1w(z?xxLn{^a9;kXb$T`6JiF+vytX~<&H-MANC0k4<7rc&FaWiMvoqA$nQ zAyhIye*~UR!}kBNQM5;?GHc`l1nAO69997PT)@cB z2<~{6K`4ocd*&%k7MAcUP*g^CXkmc;!bXY)pF_hh8j{~oTvDEFfD(AHT|0;P!n%?` zhbzJAFr{Wy=wTL$5^4E4(963doiG@it`gpeG!!I)#${IH-J*Y1p}DVrkb|)o^a3+9 z{%9wRsX7#9?WumbSkaPxTEOuFNyJ&LZ#?glnZDpfB4{9heq>}Ur48|SOpT^M7sGXs zI+Mj%fIUfk^F%8aPa)m5i9emT0V9y%xllE@mPTfIOhwGdAH)BbimA-IF@MxFn!pwB zgNW=(;$|>c;EPg1rK9<7N&sd-49#3hXJ9YHbK40ex&f-Ly%l4pjz8Ec3|8Kv&%1eT#<2r^! z{nY<;X#N9T12SuasD1)PQMt5?2dXzuv?Ph3G7-YSjtzEb4+Ib&)Ybuf*)G55&?pSj zy{Xh}^Hf5UMpFpzl<2}BWi1UKtU)jp4~8Y_nj=IVJB|%%pyg}N zb>}uTc~P*P9~Mg@kB<}%r z$xl6T{2hyp?2b5r@T6q*1ovuG(6$*uBL<(|A9P!*vzA@$2_Dr8tak>IEm)%>7 za*%>1r`7-I?Ougcl}Ml)wgEZX7^5qNxKk7Xt!;d(0}Lsw{LRG+Px{t4X2ik7%su=u%iUIDp;eNi^24dA z!VkQp$_Zhu!=)etX@GBDgjoh&qA8RZcd0q!l-6bxLGcJk%+5=`EGv+1ey=yuKenxZ9A;?C*7mKmIT*!IuHZTAm zGlRyxo6O>saG(;ms7AKrwG%T;XN;t>>r?sOPzlN!JQ8^|_o7DYjqTOW3fI1PGrnVa zDXQ8gF_Q?WDXR$dJqn`UWuIfj(S=MhT}k9+97t>}Et?#7@SCziV$L=$!oUG5;4#Q7 zFc_-k3^S+1*`NCyI^xtX(w^FCccmU_ZLtd?gH#=HkTFEg15Km_`T@iUh2>L|oBT8uI4+Ee!j|9w-I&gbR2etXjRYvJ;4Gwa z+i2N50J#P~vb9kNlSrL;;T6+&d!R}_cb|RVEI1$Mj9HBGbqwTs6GTQb^6&F z29AJie-J&tH7$UO;-E1@sl42FbkQjk1PHE~C%+ERX=Wgh=up5tbsJb6wijJVI<==p zlQnmyPd1(g0nu}munk7qw&|VKBHSoJFhmE}wOOBwfG0}UvxXSwkv`2v+Y3i?s+l-( zslLb#gA<|?Dpmt#=lk(I1Ij%$18+O^42!ad=Pm)^h{6nyxTbrz3r&#}WNZvDuwA5F zLBgmv07Vy5m{H#6zK-qK4cI| zOCM+OZ*K`-7Y!tK>qBcZ_Q`w0SubUbMtqs)db_B&BW$Qs>2Dn!pm&=qah)_Cqa@z4ut5Gl>!Rlqr4({lsbbBY!`FK(sGXHNvA9b^p|{u>J&uasMgXffNXokDPp==#_Z z2U#78tyzUfZW5>vnfcq%>47$qEGYKK0EUR+OqvkIUxKMTSD*ea!JM)qRt3~;3m zu#niC<=v6hcnKU*khu~f#o2XvU@8OyT$t$6Mof+1h)IoTQvt}{j!dQ;OKhXgj9SV@ zsY~T@P*(bugNEQ7d{6t;I}~*F*Zc`3;DNQ4v`b0`I7|Y!*-bQSIJOUE)>q72$xFc* z5+R}_iKCi16*`LpI}UPX7!99<)G?k%P3$Ni;YR0@PoN{^C|aH*onI14gdokX7}}a& z-MlES6zNud^Nd#)V`m*lfs9H&Nol%)6gW3WFsu7k&u~EpPVjREnqJ`y15xIV!D#I} zf$#CfQN|P|IKywi5uM@;aZ>z+W5Y!~U5Ki`{8>rP(%$-!5jd(FbGm$jEBgQqyjYn`gA2E2EOINr^1L_uZGTI=>(1W zb(`62=JTi|EHzRauk#>DQisI#>d+ZW5$=o2@>dPySK^sQjOqzSTF?+>@4n^2xnGJFj+65`*2XHHwT_n^>JRZOEEi z3U=F6BXQDP&tKE@=v$`k6bQy(^v~??p)tlC&~y`Yok@dd8l-?)Psox)X~JhmP^Y%F z2B^AWu||=%Ekn7#0gk#7!-MV<=MdLMp&(~w=48_{ot!4%)yOslMY7t#4V~IAC2C?d z`QJ0LLvF@MdJ{3$`di{s!wC`Pxhugvd_v;iQxI&GN+>=1p}r^eR3L=e4N{e#?S(kP zGndtpptBeK7@5$9#it4@=2SFdGs0Q!D2sE3ZWUIt&;s*XP!uprYMExLGbIN$li-Xp z2_X#FgCw`TKeo#}Z<61+qs^ctv^x7}O2(5)1BOV%>34WU13+h>K{NtT)uzM3ipG^7MW@HBkn$P} z0g$o;c^pV$}tYr+3VB-6%Dadjl6DuN_;0CgI;#hsFSpvP=Sv%ILy4mpl*m~*Bzk{ zPR56sL$Dt6Tqbx##!>KuAf=|ifIUb}N&rRNU=R#)qP=e1HbTHvZ{epfg@Cj3tD%4L zn0c@BUzudFWH3;9+MDSjrpu`Q`)5&={b{!}AsBWcu3@DB#l&nSVa zBFBrUGjOLA5f9OUeB#Py=g9c2ymSO~#jF7zu}Ty=QG`5eAR}1Od!g#SS#+QsWX$`4 zT(mgzC*jp$L`DBT_W#Xhe6Go}-m^rMEEZC=C@+EnFA#^d6a zlSbFqAyoQK9`IfT6djL-BXh|qDuKq(lrmCkj@4oN6UEmOfVIK`ZLnPr=D=!cMdqn? z_hlxPa?YVrzLWH8UWrV8z%_Ge{mK|AW~~u@SR4u!(G5NIsV0hM<~? zDoL19Nzw`)*~eD1WTDhcljEioO-=JV==a_pZXLg~v4)mhouLW#1rco)G#!KP&9-yB zU;$BsA%#h@jhhbqu4H#ZP=qE9QI&+yVabtMp<$Qw8(YWTt8Th}rh ztnqr+N}T4T*I90JDWKZvEn*!Ix37jc9Tjk{hj|_IqB74d&AZ6RKw6|IwvEX=mmJ{G z6q;IdjE)KrldNNiC4J704K2c-#$k;BQpF6;=)=N4k(a+5Trjahrt+Iod^MbAHxLoJ zA-C;`^)LI?m878QYMYdKH6$c^4O~P*1W8~Ppd|`SLdf`&+5t|r^E8|34VN>(!6jZ) zM_CEaa)l)oAEn-e!@ZKb_oPsJXd~Wl8?H&JG!Ft?Cj>>gtV0taB^}$=Mxp?|ZH6Sz zDv1?ZxoM9F&4UmIyuWNV7fIAQ3XYJ=@Jy#N4n(>Hx2|ocmw5l9$O%EHKNP5^aB}M& zhHrd9NOOZcXiX2v^aVnr?Ut(VkAUNBC3@NIW`m)Jp>H%tBqO-Nj`;FlOw}A!oxi@j zk~i3vUH%=gQPG4@l?yLLoC)OTdq1js-e_l2qB$fk{hs zqM0PAv~(b`$43Lni#m(qTDZCQM9N~nqUe`u=1;uX03hf?(up_a3<0_6E}Ew0?hqc$ zvz>ULyo%5Pu>PFwM*+mhIobUUTOBi^-SRqDCt)!0c)&!%?*D0oc&cD!04if8c%O7D2}6RfZHt#jed@ zu2fq$BLVPpt$U4Vj*Z!-QyuStRH)oC*_f=YP*}BfRJXC8lnPT;r9v5T4^*ba)FwK3 zMKvh8NXrog#~?@vUnIW2ZMHIsE&0dkO03O^FzddZ46i`ainqa z-|6JGG05(|GsJDEt+HGS0l5Ga8@9mrTyn2%U4nBFdq8kL^w=vUSe-yEP2B0R>K4I3 z;*)gI88sx%-}h74eaACGv!YNTvktC)EZoA%?u|!vM1AG4GS2&fL8+`=35$foX{8CF z_O4Lp!Bo3j(a|K$e17Ic247A!NohqM(i_OPx3j)gAQ(LJ4($$v=r|_hu1@-r_6{_TI7hM zk9<O=&j=a|}T8btVSJYD%mU8|AY( z;zcL`Zwyhvx(f;D-Fmo^9VJkR0iDrL!~RmG5qmrK4Z|R$h(5QXo3sZ;8&L+btLP%b z?^VdcYqGeLyF_eX&_l*U`I)B7GBx4MP_Bf}5GeWhWgS#x;+d6I?Kiii_L-Rx$5lWe zFyvV|0z(0dHn^ElD*-YI-Gkm#Mnnyq5co}{toC;CnAlFRfq~2uKuSRR$ zPC-`ryvqDb`j|C&thuI12&E4KVyyeE6IweaSPfOol1`aaF+r=DkMB9o2YAu}u@BpT z8t4-1@FO$EHY|N#@RB0sgeMnoOJ!gCz+X-{Rayy0`5xdd56!eUuEv~Gh4A!c5ip4_R-p2RQa9FV21)CMEe zG9}yl5sD?77UFGnn1ujO6kugiVik5&@;a?FR1y(Ecf;-DsEixMPD71Z~j0NI3I}3=XnX-PGo?|cOPaZvU7H%Z8 z#SQa-or*SSvW02p=9~mldPi4MVN8PnTc8-+=nNbBHDy7EP?)KdDRJ0H%-B3v;$bF^4f&?bPR1#qs63Z97rWzN|MYY-)?CCqtgWt@(!n$cJMN651Av2pn}! zpCeQm+Hrou?6k?ypHzO;A_1mkNRR#;phXJTAP%q2Shn-(+@B~Xf9gK@OH?t?TS~(M zuHbxcswn~}A$j=&+h>onJojUwrql6-K zPK2>uz&-i%+DO+q$wJ6-WIxhEl~@(PjM4}eStCxf#?p<5yV4mEg0^)3LO)kSh5{f^ z-7^fZ=h-un!rQyev*<1j00@KB{7%uc`62k@*=So?=PK(R$&~n%uRR|NUeSSVhN;Rq zxJI&hC>l2@#BBs=NC;l&8i1X-C>E%u3xY(OYysYSn;kR$pmC}fOi|CGRCXRA%p2MG z+4q?eV=&Edz#mj0`MHM!C>mSLND^3l<*>BIsJg1 z(_GydD%=l^x^)XEOE!AO3}PaJjR3;HDnTtqD9lVC3W+!ebj9c0ky%bW(;K`cQbLY9 z&90;A@5#x|&yf!uFp*>d_O$6Tv@0g;6XHxIA8#0d21JX{=_!-|HHZM(COhFu+8ON{ zl#$cTj7=F(M*P_39(BtXg*pA5rcIAC76Sa}aZg70iN^nWfu0blIw2M$3^vC-b4^$w zwMYYn%pehDhD(47Vu0fv8Cn`ClH}W4YJYKW`-K*y8t9;wx_J>_8zg2O=~doQ)zeg< z_oTV@gPoD(O9s7_Se8ug5DojX^OOKQghgv>pkf*iuK<907zXMaA}oAX=*FaUOFk$@ zyK?h!n44r7F{%!(#O;bkc7%p!qDp`#NS$hjEN~XVD|R_@7r19BM2aN7AmkK;HgUY@ z*HRX{u&$B~@{$!y`&Myx2J)`lUMr2}%;f%ReDb3IOk@ZY~{`hB|<{W=bg> z;G6k|?Lh!Z9$7U)aV1bRb^O|mDcI~Lu^8?TB=EP5MFlgK_Iy1}$D>tY$-QPiL{igg z*%a=v!5BEwI&`)$J*6dayuAcCA5~3Z^w*R&T3FwfK+upK#6)*z43Mb86 zJ4=j2)7Q?mvmZ7ECN!nCSandDf=YjJrM9doS#kO11^x@%V#rdRI1xKb$tcp87Vg#x zLxqqt^5n`k6T#)&4GG9*@z2H#+2~HZt4vl*Bf{VMLt*5{b^r<$2RbskdR^Rbnp#I3 zb{4ly;!qCBv~2QuHF{|!P9ReIHG0F|Dfo=1(8keMz{ql{?4DjU$XMSQVxkF#^yOPv zHsu0QZ=W-S+&d>a6Md{eTTkRb{G6eo&D_xqlR4kHXvm^?x8o#ZiO6?{#E<_rWJy7~ zw8O)dU<@#qdH`tI6^4USBVYvlrJW7*06w`=QRHf$#BI?L&*PxrkI05;=xpF=9jodc zA*zCa0XTgxx_OQiV3%l}OXV4qOHul}gQAFzG868_u%cBzgFQI(y*-B|sDx%!ZrEltnA*2q7#aZXLetyv-5E)X`mGplA2RxA*AEirN>Q)2 zUXfedmPXB0K-~)XVoC)KKzAr$zDEM&1J+=(2!;`$@2i21wQOKQ0M;apF$HJGPWB}r zrb47o7aehT^?A2XC`HF6U!8! zzLzyBV+_j)k9HHf6`h8JOosLok#q8gGMRfOz@5a=L_W4mVdhj8Gx^Xe(2Zh{80Igy z9SktV!!c1nF)jgKN|_P?F}Xmtl5j)9JV??`0VwvKp!wrM+e-WX4kxDwLph=ZltEp)4UY?DlpY){xNbtrxQk(@avnJ+b%w@=s$nQ#8h*LZD{dOj}nTqpM2lMYe`$G&ZKx_gL zCr#WTF%8Oal9BHx?6@>iu;hkeQ?Vho&d+gf4zZ2a?LEr5o{2%o`|lh#Lt*KO?jv(f zjgIwbo^1fFe401g6RsR9>H3ibZ|C1juydbu)NlJY91mgGMZHFzjb#Z9%97D z@e{`T-aEQox{;xsN~U@{R9I06*eV5DyM2p?YJ3rXLxcl4 zuz1E_ggHBWDZli!R9<-cpe>su0Q=DiWsORXWa@WFz8eM{oR+|mQs#P14I?s2p){C? z0C+t1EX%SQG%$KY6&WLpL$MA8*6+~KD9?5!nO_qiS!nQA48C2YkdkIAU-46WJBqfw zD{-h8w|Zd6E#C6dXUgE9@X$U*#UR^ zaz!rbhH${h4Mex4$r#XL!JWE`gD<*LXZU#y^mkbv4n>62(V!k-s4Wu$KZ8pXI?3jM zMr-%%FWc;GNFii!24#eq#beJ>2szEGLHW@wk-cKB1V@5$0ZMR;6y6VNzEmFOvbN${ zeU|(rHxK}2(sS6V)5~P|D?|*>nEb=d$tg%8a2y78hNFI?5MoL62u3w-BJw|(&0v5- zKm!aW5(x+lqzCo|6aykntGsSxYs;XC`jM!pucKR5P?_9(A9|&HudB~)qG^s zpI-c=l(lTqgOS2A=A)WcNy<;2!9%eCZQB8AgOn}?FYy~>QF|Hm+Z0Cb57tPGLKf%Z zdcdmTqc#dT-c#o0h6w9x;CVkmIBg{>g^d=5xPsLnmiSL&wdOoIf=>CiILh?pOpLZ} z8`J?9jILSoa)LFQN8WS8gIa{$o=K%M;NgWM45)jw4z)oUvrwo8Y=G6#ycJK{FtI18 zP_Q-srKZ00TKL-cSmg-U%oKjMHIpgyPJVKim@f(;S2844>jVp1wo2cI04pGa1i6c| z5XURLc2U{^Ny?{jmSa7!)MlT}%84{~Gq?dv?-BXrylonYs@%;^_q)_EmQpqfLlT zhY|rK2Cb+vn;E;!${tsAY0tG%Sjcn4$2-SH9{?aIbNE`-%QsenCPsBgvZEv0meUs@ zbUG^FZWz}@Qa{!;R4iE2wd@UWDvSYa-$g=xM0vfWAzl)>*ps(DhT_E%(9X*CDJZg{$;mr?r5Q~h9&xuR zQm70$Dl@;~2#1VsT^Idq)a?f{SdmVY7t#g>({z^f0>VAsoB$k9PS>PGQ<O{ zWC--q3?w@1LT&+K6lhLE2*tesJ%;1@p589I5iM{Ft0Bo*vb+-X4`WbRGO*DXg>^;{ z8led^Wwq-CVNyxdPJ6@DFYL23+6gxX)^30T1Ldf`q_XzB%PGRVm{kRwLE?lr{1aYiJy0P3 z%*!-FjZdfW{)meRF&UEG!Kx5=^tZOd`~D|X!hjMs&Gp_Kr5*a6G6Lby<#8}uy%2mv zTH$EQ3&VTT<~h9WWa7NH4aI4(T6f7l!F6ivKzjP1=-cUwxkde@bKp>8rzW4 zRCF@_0_X-TZ|eaizzK4yR3qcgo`un!QD#~z?EF1>BGazimMwo^8btt2B>AM|Q&<6L zNKEa(XC6^e0PE={tN>)TOyu9=~Tc<92)Cn z5rnt(d599zaU~NQ70}F0cQQVOIWnf#A06BP%ISENOI^fj;uU(oXEHm}0L=>R9^--6KV`62$yEX5ShUY64pfDh}oeIhPG`{?Sol0}N5(_r+sTW83Y;?q$@DYfBr%CnG zGMEP__bH|D6m^nlK_-=bRij5;GeZFP#J#(r4`Qyg@`kJmVI~`7%9Z4*s-Nqp?{H{h z3`qAC@+ORJ;*kI*HV;?UA8{OA7!B0HJKK%>(SWi|^i6x<^7a6lO;GDQLP^nX+rABf zf4R6DOymz1R~>TG%*%T+uhvV=MfFtCs<-q?nUj#G&IT1Elxj2TjA~d$#Z-!SjFJ{$API)}tsR<3|cn3H+@+7vC3Z{q{WXY4)pgweDhb6arAO=}=nY;?wv@5jptguVW1(?nGFK|>DI)pSx zQ-*TcZw%EiwYIagQ;2M@jHAs!Zv%b|#GgR}p3doou0;2AIXIy`=s>Cl*|&HjTS{#X zVtS&yVmj6p&*SBX$P+p`rm9cF2|1=f zx`rs+7n-0CGtWhOano1;2Z2E}Ax9goH1!Qo9dha+WFuKkDst2?8#Nu*jjP18Fwmcn z0v8w|cqBJqP-v-%ApbqkO(uUuL|!w)7;|OCMfK71bjP+g_7&Uh=(9*hbP^T0rWn(0 zs87j;Zq;c41YmY;%o|Y#zED=OMLV%&x(cFE5ahd(B(p%Q%;HW15@qPFL)LUy9mjj{gR+p*6cz)KUgA!{rFaScMzGzGa;0WiG$#PV^fupkIf zv8J*#v2VK*P84D>=NDpW;6^HDwPh z4ec}Jqq0)4tg{VSMs3DYvPDm6{>d_>@*%QlF2wF^Et^5O>Z_w!#g$@)DtnE=I^zmd zxbL%|V!4u*t{{JX5EBF;1QI}G6tAo9OKaof=oCaF5>6mh*0W=3?z(e7AqFK%y5O~F zrrs#0T?6hmPr!4N@PrJbYhNI(9?_S{3KlXEM3o>bvQ{YSRJTqw0_6D`h{%13*$G){ zkzj@_M$t&nxY>_AAhMEJq9nNOj0%_u#Hg)$ zg9*p9Pu$cRs}VvD!fH1F{+XwuZ~XJ_Bw4%Hv^-uq4B)v^B~ZHo?&4|u8XCOM7RPpg z07}GKMooXGRmQstVOp66|KcFw0DnxULR)E30qoRc7jZ-v4TZ>?ISGcx!QO^C0ewLF#$mW#@ntL4 z?ssjK;%r>m8EB|4KMyR~S)F_`^kh?Af}^g0gOXwm?%{PdS!7eR>QL~#07+lG@LWJZ zjv_vf4IK9IZZraP3FTEHaczLG_tc&y+oeojnn19uTLyz{*ox~XO;4m-aj?T3DDX;F z#6*@WP4`Q8Fh8=yO`02OdP90V24(r709C_$%pMds(wt9OLqkm?`>F~cUFC6f1(8F^ zfhm<8!mx_$2Xa4ok63}iZ1t=#R9>?N7c;SWgYwo2b{vpJPr9(v=Qyiqg(T(<4lc!?}-RIJP5*;nt0 zG||K&&_g<+&1n0SE?raU?aiBideu}xX2$wU9Je{EpP-IHGp66bflgK(K_@{2y9C+LHB0? zgWMEiorxqwJ(i6cgzjz*@kfxyrYsyZ-9Ux_Ow)x~+aBAbv9qaF1f5Fs0hh3=ge4Cl zqe78m2Kz!CXtd2NOpA&83JKJ$C@CpERaX=d<~V)bm`N=hTA}aA9^2KidD2?&-#gSb z;Zf17eGqfCPfil@<7FSUN|)Hnvu44Ni*|KXnoZbDFw`K>RYhsD3StCrONAL(na6q ztqG{JS+wcR0L!6-6n+iRoAjWToV)%1Mph;_h?$D0Ji`{$QE#aEHVF$RU=6U1)63xV zR5)NH9|)A_$*zPl!gW0gY81rGa}X1VcEaK0Kl@VKxNe}5PYw&yXx+F!^er-EZjq5* zWKbfaTum#Aa?%rYrw)pQyIm>G-zF|k4JYZ{0s#l6kNC~z^#G-p*+C8(hfGr=8%ptx zP~gm;lob8Flgu0{3Y!8C;093q#%Kga6jtr9c4d!C4)LINy3aHlb4K*Q|gXG{n zDfoTQlJwUm`ck2`OvyxMhy+k$<=nu^HzkL%!%Tt#^MOe%CV+)I->wKDV~he~Kc~xb z&lm{NX24u`K!X$AU5Og>FjbP5h6frl)|nsin~-rq%4#-P35U0y=qDw+F9+x=pXQe| z5xIo4hyclh*di#TJscwCP?~1`oEU~ktb=Ww*ZA2HyS!|(6YAL&L~HO;yjv_P&TZQz zvC8v_rSFj{QBUJ2eSUXK=K~#Ss_9)bC=9db# zTbRDl=VYf-h$uy@6!ujn$$N$zq+Tit<~b8-b$&e;8feP|Q*-9J>Mds8$va$axPwXVZTlOd6J}Ii0?tM*aniF4+`m0 zI@*LRxP*^n$Ei3fbm>3(h-m;4Viy5Q1O6MR>#5maeHbhY9x7fmkq3lQI;98L=|U*y z`RWXKln9x#c3mYr56+{BD!wY97r_}~PpWl(DXW5$T{H4{e|}K)hxp7}5I0|}LCS21 zmed3l;5%F*4Sc^Zz&qaAfd{E74oPxHbVn<0WT<2T9prSiTuc&BlyZ|L*@O^#TYWVS zO@|)dmO7=lQ*t_JQFy9Px-!-nbF;T04@BO0ue5zdl%<#Jf;ke3Wwp`{vub)G4HZY> z+CMLT50%Wut2_!;tnr3>v|Ebq34OI!3fL_6v`LO6yLsZm?YD^=n${^K z1~T+WPilRPew^JT$n&wF`I3k7pv64yc2l?tBn;IE#P(RkVuoQIoxr98%?Z`MAFC}t zj|qSxVo%%CJ*uXZh`viacmUyBCn1Q4@g!pKHl3P$=;N4SUZ}nZ#X%Z$#KZueUi)e| zJxZud=ODDt@j|JvG$0;R$Wl$|cxB0}JOjZ#m}|ilMr^x7r%Z|itOhacG(*EWrO{zv z3MKa3c@)NHFphlcG*D_A)g(KySBS`a<;@5bRuYD+@zMzk(hrYTOtlg5D$t>M`Q(ee z*>yZ7ESfVEdhrhs4Kzo7Ek;6uD;dgBPI9k^z0NctH7mOqp2rroJge;%(^N4hA~v;3 zqyu6i*2!dmG-Pbofh|0w7yTs~icj!OR7We3glM%KcvRC>6o*>(Rmw)n3k(4(YQ%h3 zUJ4-Z<&eS&B>vnR^|Z851D4K*MduJJCEKG>-gO&qgea=um>zMYwqHk-)94uD%zRpM=-AqX6^NAn2bGjYEO+2k8lc0Uv;T)_(TxMw4u?7AF^GlBQ$b3 z+pm|+qr)NqE2oaJoOY!Sym-`N%^2XJ`j|1Z61yk&V@#b?raxwU@nxI1X|Hi(LnC@b|E<8?^Gw ziAJJT6zzvXMOCFVwX%||v9vuSow-CkLmm>j1V!)3o6vp*p7ve_!VUebskh8~9+AT&6pDC@K#7BH^`u%|o9r$>f?hHbUV5*}<+ zLXnYXrE;M?vXG&6tB2dY0UJKna-uOA7NfSFSv<4#LTK)j!!p*G4g)D-c4qBP>3183 zbjm7j&^Zv#mm_F&xNV2<=|Nc)$u4$bH0Pjec2J!7QN(p0?vnb236rUmETTuLn7|4i zMT<81w=)fJq30+m^c9;JJ*6bmQN%a!CU+s0$G0ZMFiB-kP*@i!Mm0Gn*h;JXv{2>0DsKZi%n7fFIrpJ!z5H-^NGU{lJ7!@NQ2l-E@_aRDyMao@IZ_71rNK!evW~u;3q6js@zL2L0O1h!rwHn{q z@5Vf+rZ8mKDq;PjX$|Y0GFcIY`0RO4P_}{vhCOx0&zio*YmwVu(T@3co(l^-N=xvm zo$AFi4?k$Eq>N?abTQbc-J0Xpn z)LM&adibm4GMoq9ty?BRGyu5J?DS>dmE`;A1g)AU zc2J(~57l)(t|up5&}%Sg;_fp+L&2W04Z;9u8%w|s$c3|s$%ZItejG8B<6G5a#GwBX zI6{NQIKCws%?Q`Fqc%^7m!x2bGBRHNq>hP@Ow}vRMuXHWYu9u&Dv1_t&oQOAmB~d- zCo>1s6|G~tl!;L340e)r`?AbDSF`oQ)05HQP{{8vJxnfGY(Qp8c?%Rkfhz zQC;9y!P!O$<&0y2XkZ%P8RZ7x38kR;sLuW(+m?$q$B;dBe8X@*ucG*}`VKs4DLb>l zl~Q}!vzD3OrZ82Q=u|X9Cmcy$hb)%vF)7wAhC395bCEsy7qH z%S6KmUmK%)283Nn%jI2Sr20qFy&g8QHyBkgxnyoj(=56&im#{LP2@_w9-0Wr@+--?JFEeIMXX-K zys8{QuCQj)7Y6NMcPZeqrYT^ZC*D&$tPVPoiH1Xj2KE+uikJtUkt%d!hr*SF3<@a- zEB96MQfSV|s5BA>sQ^Ne?dt2|`u20SFVrHI*i+uz)*wHAHcF5H zng9+bkabpvipbCr{FVc)k&iw*u5+7*yPwdfep4T2IpDXoheS4TDZ7bXEnGMDQu6ce zF{e>Q!njf%wwr1I>hW?p!~r1A4P(L6b|p{5QwM_@#gIqKyQ8^?pJW z2l#~ZlX_|tzQ2fj&5;0D+*Z_Fq_J)nvRFehT-}q#YPKT?`GTUfrzY`qL;@lVY^aJX z*`v?f)Y)yh{9LMvj*JWeR;Zd*-PBBW(GiDIHfyZWjvO=1Jd>3PyD}JDK4FwVA(x5I z%F67q5+Y%>R>7wIgHaA6%L1PpG1hXZk{~Tk^uLoiX4~3}zcd9qbgmS-bmYVf(OJbx zxpO7-J=%LQW*4@s3sx>ydh3Wb>g;k2Wn-r(r;#91GvVixyrz2A$ZF!z`H^Q2sID~v38Xw@`?vCdkFrYHz~^i++)%_!jv3{? zWdLf#Zx&7K3{t5$NzyWuBFQ+tE?8eZ)1>(A2RPoSuec%vZ}fx0CUC2x zHIC6Qia+1FG5u?yOTyAD#)2rRu;S9#RghsYWE(}lD*;)=P`paECL#}{ zsfI)q)*S^Dm;^Z@U7oSun{im-5nBj*ksx*um7$hG?t5$wvkh)%n35vfKCmTHPztwD zqBe%}RD+9uaIQEB_5%89Hz!o=~qq_S?8$pDYg7o21e%#yTmSO+dB#%(3d^i==3CXFMki zAXHOQ4UpCDc`B)@I77j`;u5gmD@v>RZ6F!|*qEmXUnt8q(YSeSgs6rX{OUnb!|<=l z3??@b3vF!?3nzwI5Cv5R0;;z}qgko7Prs(Jg0+o4Ds9)CV3&9zd6dy>SUY4`;Lc*n zo%TL5kV9Guk9jM($gsVj48H{tK}_mf`4iVlTXiMSMs#4QX>2SGjjx!3D+ts^i)+G) zCs9LjW3mbmam9R!&l6wPm(b#e4 zjviD_Y2m7n^=qOCdu9!?2|W=70~`&}nZDuNQIF`9&Wgi?s(^>wOHwW!O>sxxhr@bHvWz~u;CFkbU-RGWX^Nnh2Y0SCEGS2Rh&V*b5dGv*hpBfZG^ty6gZOPe2EIK zmsjcvpBD1sN;u|XbCPQGfcT0Jrj9vP(GV&{Bd%1cN+AfQC)oT5MXUAtc=tAikcQKT zI>V+ph_uC;z~BUa3_q>mnCx?bVr(vW+|F@%6;`wPz-o6RJ1H%EKayqhbLf7AQ^Fr{ ztDQ#cdOhX@c&hSfLprMIT}Pz@((=*>m$o^r$a_#^ZXOs4o9`nYZ5ogdz^1BlfXhk- zkXf9`TxZ)Pkr1_Y!>BJm-pnNs>`>3prIl%5R*f=M3Op;itI_kSCbLx8Q1sv+RK%Lz z;%;{;Upe+`+wqT_vow}oo&`?{A_(HpuE%84Ljb+OsM#M`A3CT4WO^lonq=j>+0Q!D zG%8+bkm@iv&>n%K+ER8H?IYb+Ausalfu|XH;Q6bv*?@#H1(Ulfg#(R@XnRxkwVi0c zLAGQUayN16Hn!W7p*Gj{=fe40s$H%GZzea(gLESy+ zW#l{_aH&pMg7q9%T8%52uo1kof)cVgP*b!3Wv?m~KpO|w0pp{g2n&splNc+%%QhG) zSX9+vod9u3fuvCjk&=?n6~*I`q;x^c2ti6nb&6xJelZFfhQK`JC6rlo$U;L&xec&k z@NP;Dc+j+XmBH2A9EqTDEacS&ydjz@!V#Alkx&lEbD8$tl`M#Y6hlLJ#&?3{D!$qV zg_w{mP%lN-2`Rbe;3++_8bM7d{Edu~4atE`mqJU(0qU(hAweuWmDUVt&y^Y>X9*o9 zfP0%>VF)!_6o{4nOLdQvutR%$5G>4D4?0Wv;3Y?=IA(>S%-ApZ5;(2Pm6{=#j$sRx zjjOs6bSG+BEEsEmZ?8RYa-xXfLWX>yC%L^!a;$KXtnK8vZU#DSKDH zs^o6biOr&gNb5?hu?P#;FWErFZ~F*>^b!pd8W12wVk4!VD-6>p4U#<+i23~Kh2DB0 zfgxtmLHhP=bxo<%bMaBJR>kam`_`h7C#2Fy^?XkJZWlNA&K_g0GiuLMtl5Ott-T7f zM?l$YJeoql1q2X=dyA0*JPI)90K_NDHS5W)a1eb*S7Hz^x6_^JvofNRgNoE^r9CsL zCr=;8VKj#4rxx)6jIU9xQH(^uu#5H>OO;#$6~sN6M2(x?P5@Li zqm!j%CyXgUmbG4c-d_35e-L@mmuBfn+-Ds%+Y&q zM^HEGRpKiY2XHm+t;m9|>pjFhPdU!1?Ih`yM@}Wf^(#qBa0CLCE6En;aggU&36&Oz zA1j1iQ@b&|;UiFALYAU}uppr3wzYriByxiBuyCct6dc_oDo_a;xUN8lv+*-WX3F=g z)|I`CoU-t)0V!h4sduXpW)iJh4fG;v=4k9-TpUAS)s9s((gGU}2U(Loaale%N{y+N zd6A;AJEaJ>}fkXR&uKylp{?@9(-*q1B{P^|CZ zA|-zWg{Cnyps=exaftwBjqHe)EcixfSp<{PZ8N(^v{Pl`Uu-0?6tnp-s>lnmD7Xz* zb0w}OfkbNY<Qpph7lX)q)-48(`S^Nx7hJcm0F{V(v@u0UiWs zVvL)<1t}08Ap5qvlj{uIW1KnG8Vl2FMyODpJPKa~7xZKuX+e5#4xaPMBQrk4;WhyQ zCWI5Lg@V}Sa1703;!Tb&v`wMC0NO7mJp(n8t$yVKR zDoo^st~@b>b+x5zQh*OR}^E@eFpA?mbln z0Y*ahaixfKBu}G@(A!*Nz8oSE2C%|FjgnS2ug@N#XlpyB;IIsAdwSasDl}GK2R(F! z?()b{O0MDbdGrl6z!7~x%dP|nph#*O1>qYViz3AX(5;y3^b2q+RQLN^%$?Nk^eev! z=e;Fb0-?4-U$j3*7Ig`nLMV0Wb9jg|E`>I8B}ECv5BVSYCV4xlPP)f#$(b`yDNc-n zD|Bav;Fm<@W|cbeA7%>L*p9GgMj&@mBEqP65Sv{pyz7<&T1>nmmBDc}C+`IXN^cv% z!{SudU@MXn#DxwtkS8E>rP((MsnIOb!KxaN76n-;0uSg!0?K62S%|eb88b1I0(f5GUi8)Z;VDRi zaGdO3 zOqY_iKGcn)#;R(AC@|19BbejM^};dd&jd#_Tpe5?<6e?fCEh3?ckknn0T~`Rtm}ia z9U^h)Ph6F?rSbzND2Xf8=+L()1wsj?vWPt@8o3faucm%`rk$l4^rVDPJ*%5Z>+8{8 z9a$<6MY(d%w{n1p(pFDc0ey3_`jXD2lufJkgo)^oog%2gMR3IasjLCyLd+rtJ4f~i zCPYOWAPV~_brOW7;>MscjMwGnfU9am_?zvF2PBliSuvv(yo@`-Lj4b8;age9Tx-}MGuuZAma&0tKVJMnhc0Q1=d76s|N#t0%le! z+9j`GE$6K(abNlZC^Ev2?VGHifgAiv>gBFgHz2Si4bb1;u$xPV9*rX4o$hWgXMa~K zD2LT{VhfuI35Oe5ft~%g`An`vF0ii{zx@KbR>>l|C~F-DoQcYwZVtq`CkfkDz?qxu z%%;zf0l-0)g< zFLt`KifU`#G@(Kbf#b5!WLd~q9l}WqE%yE-Qd5w^`U6tJIlRbAfNZZEVDh23k;;9H zo2spYzYru=3$bszC&~k+vPNDF$$nRf4v^vynL~P27GI(#0);9Dlpb&k+1nzJ0L4FV z>cztO(uQ{ORic=jIwT=IoNF8V?2DkF>=0L?<`gjz^){6=ETE%ithRa;n+eY(PNaJ% z{Z#<4k&+1&W?!1OY+wo&Q9GtmML&#E6T-9#LUYT+buTf2ZmuMDC@ZiEjDSF?^W<>S zp;fCMyHah#mfPqIau%sxSwTYVK_9Dgt*G)*SrAQAX@k#h0zP%USMiedRc4RwN$;F1 zDeM$Bs80zra!%rh1WFqR zE5-iFI-t8bMk^5?yM$)I6Zawy&Hw~eh11x~I((E^HJh03t`!lWzZ#Bg{VBszS}g3dQ>)G1SbGfArW@$xl~>X^r8C?{kT z+>!G0mF}LG5~-I%3v&m0NV@W>O{Th21;G+BYrDKxL5rV}3b3r!EMXK&AUA7Aw+pHS zB^>!*(m;u_x7c(TrIha5$rO)ZB50DCb^lm0K(JOx;U3<}p`UH5D^c2{as;$7()1qN zoj3+WdF*lkwpcJyS&*YDz5u(z3;;$SFqeR+g`$PEiyGK9LVOrSt={kgKPt|dcz-{q+t_SVQA!=Yk^73 z7s-R9CeELeP0rB`8Mpi08x$+T3ix&bjHhb?6$A~WiL&e2-<}5NyM_xpgi!_NkglrU z0T~?;z`{>ckbxC6#oq3YD_44Ql|#a;90>6aN-t^dN_!obId!TE*s?Zh$pxKFK2IXmZ;_5fpwVp(l9lnZV;^FO?ys`2rn?De4|&Yj1< zYxzWR`Dv@;&*A~dlc1Vv-)disT#UPJP2&so+9?L?G{)hl0sku0pUILf@<56RQ1^7jxPGc zcPoeB-2@#jGQznenwt`_&#+({*auFK38yZOQO4I>I7|tothB;dM=v1ClM9_PSCW#{ zGjUVg)Ka-VI9ZrG!al_SD;gUw1>h>_aZom|+I_6KeVr>as|oe98h3>MoRNJ39U5#p$DN-433k?LjctfZ<>T@=Ea zdfL$uv!)g3w$UF=XU{Y>^ zDFh*Tv;t78hXd{0s!Myn2GA-qsnUgC$gSQs++BlLg=4~0eFCtNLILeK-?PKSzAOht z1HsD}1lh3}1gcsLi~390=i3**R66jC>ALwiAeyFIs!Tm6MT$(rAR(wxiEzaHCZFP- zsBT%=Lw!p|Tjav!Hcrsz!;a+_GH$wN-Y zv4cw%+E$h=pp` z*fR}0HXKP;MFDUqzHAkSC}begz%B=EDmLqOu$Pd4=w*%-r_@iP-K1c63^0e;ArC24 z(|?u%{I>YO$KnTB>SzZbm4ZJrK9(uB52~THu|0mp2t-!KMp=w+tmZ$JmKzZibpASd z#4)c101RAIwB}aub)5qyK1?dtf?xCOs6X}T2<9#!5jGhr(jf*F*}&@tNU{59F~&mF z&X})O)-x~%CqWUmxg``RU5th*pgpE|my)Gok4y_tx0|u#i#eX`l>ntj=7TawHaZ+? zu#=r!Wo9b;k^t=&ZmuA;mE#QX>rMN!cDx~0K_+m|cwr2>!*6NT8XlRyShFSOL9qrz zIq*F5BtoJEF2x`;SF)#+hiawDo1S;cUR3lHY0$QpBW{Q^Y=v5v_Q5Ni%>o?K#e7(Z zUNo(>#AeOA+5rcKoV^M+rV++A1CzRvwPf~CRn;5Q*aGHxnvb%K>qI@r!D8LS?8vjk zA2pB|6bAOz3)Vug8*B$n8>THnlRA|WqMkdz&tzL|M>qs>scml`2LK%8j4EniSwbL; z_5!c@kJS3mDV)ST<=aOb{9zJ73&+qx^$v5VD+dRD$+cl@HgQxB`{b@<<6*g3fe`|p zj^nEyLNHh?fkwUqU#ygJnlB4y>&O%TVgq5hx)qFB-)vM9z1*HHx`kfR8pI5jZ39)6h>%S!aHdT@&%QJka^10AYJSeXM$MP+MZ`3%#E z;L$ZlqvLQFjbtJ}?iW=&5{xURUa5O{MtNQ93?g#vVVW*klB zIe7Sg>O0F^DNTv)$iA|f#IJsWe(VP%O|&YCZEY2>hTE#GISm96-jzK5++GdJQQ)W| zU9aJ-_B}}-t*6vNiU#;ql`igInQugS3)$yviEDd?y*mkTqS2 zsP0K3X>0-TsRkMNUh>w$#r#zp2kIxX$yY)B2*tu}^T!&NfQlQcqkyVn&~@0!1!g~D*HwWbXk0L>v@LC)GH&z` zG?F(fCGHrgfQ1}wSjE!&BX$s=TbCcTK`K!#iS7<1knWfLSIz>Es)7&cgKu)&z ze6a5q`IPfgc2xgRXPSth(8sydlC7e3rOIn-2cFRQ9MuMa88EHyUU8=SSF}U7CQVTd zf=Lb!a3mGjRQ8_dDk9J>W6shHoGWxOz0P)z^HZ{B-*P4K0Wrr(;@Y%16Z1g5SV>i% zy4J)aM?i9O_X&HVfGX43u`2*>=Sfw{=m0&T8l60)GRPvi@KB;dhDxz8uEbIgL&}=X zZ9*1;TmXr~qY%ST*dl)05@Iz}e7{V30=mz_UydT$qS2!VAzC7wMxsC;l4J z9@0~=5-PA5&W$oj-;f{DumZEx)J~sg=NDhY1y}8nARlStEh@SNE6-oRIuz&4 z4vNWDQ0zIOfo%^EmjS|x(Y6GG)l4ob9!p!|Jy0d4sAn7+aK+ORAwWUOF^mksq>(ov z7F(j86K?BXSL$Hel&9@Ix{rE-3#?wE8a9=*9W{rkL3`4WWix@Mp%QKm`(0riAuUFj zf=qlsgxC~RCu{D;aEmm7m=6HEF&z2PUM?0NKM-P^5Q~FR3F0If`l8pF@BnYEr2QQ9 z?kQk1_*rbHNcGQy3xJ0(W+5gSQa!GOmLKs)Ob)cAsC-?1*3D016KT!B#mfwv5n5=KwwKI=+iz;_qG9gGX*lJ>}bDWXFPn3 z6!{WZHuSr9r3lD|2YHa$lp7KW;7B!gB&7s0VVaP4;E#H79o1xxP~ZoJzs#&<9DbBj zYb=4jRT~)*ghbAaIPce<6Q2eI_)R^8s zjR8K68vNOCBl0&CN@yhMBSNL?MrkM@Mf2^5*%ahO<~4v%niZ;Sv%0$YcI2wSos7!Q z1wObrT(}}#4Z7)txY0~dwr%eV2bmEz9(1lW_&{w)JAkOga?e>5h=owqdK9s4^k+N|ZfGByw{`}`kxH=$_ zh+)1frGlr1F%r`bdvnf98*(4Ns$3H15RHbIATgRxzGX)_*c%w0qok&~zLpG3d;~Z{>C0R6-q!5z5 z{OuN#$CO z(|IM7bj+efxL0bpiVFQs#FnxEV`Li(h%ke?b~Y79%G@ddJP=ybxq}?>>TU3BhGA>| zuKdq30K=@{(zFct1*MCmBnT5~u>^oV)sw8&v@Jw&w{xT2_X^mkTHrpsqbGW3s}O4W20bHWY|mc)9ko@I4_{b z^d*+lVR8;+3{Vj9cy(uWoltK;Q@l6$0%|7;*?djfstd-X!@Z%gztq%4dlt{f>Ckw&}25ILRmv4c2FZ(Xur?#gi{d5@&lNhS!X&P4a-rT z=QQD++&V;x!_AGIHG_6%8L`Yzp-qVBb+Um`ZrOtwuG7NvwgrWSe3bZ1{S&E{9%h{g zqI6f{+Ej#*hy`QZ1f@4dNca&SBKEv_Ns7LbYl(>>epf&KD~+p`i@|B{%QPryF1ja_5f4GWlH3oN~BaO zmntoAi6R4kX$EHrUhGx3bN4XyHLqPgg$Z|4K8j9=A_qWOpYve%>Kc`Y2%)ZoXw?T; zU!t{>izk5!aWnw7^2`>Xk3lMY>9{Bs6^O>5Hi+4GrE*oL(A)eB5A&5)qtbM2+Lv}f z%DM2Qd{Z@cVk-y0<`=tMc}bGWG9YXCbi)ut;hIk{6L2nm5=oeQL~j`vj^oFvDwWu! zJcqhn*kTcEhE4WDocs`02cpG68PMU`I}VzlT!{dzO!L$tmsMI^F#trps;X$#9F(Em zquCOj$*xdZEA~Jxh{2bGcYq)ZXNn`14D^x`tqN%hf=UEzGkx2Y(*9i8`t~N#EC&%i z@*QtcQlHLoyp$lprXXe`^Xx|{JJ&rgf&Er55A{EA5^5JHxfp7A6&~WRn9EGx07Lw< zH6j4`o|5U{KOCF&#oqDR;3OWhW*E4(_N{a(ehs`PHmBvMxq~Q{gB}wccB*7R%h`MX zq!{b%O2RJ!8cl|UtbJFXx$h6;)xr)FbE%^s)LHlf&y(NW_ink3(5pT~0!|mH?!x|}f)$x$|5&2<5o;Wn)1fKF>Z%lj>!D^=(i5P3 zCSh|vlmH$kAZYhs!vJB)5V|6q-5PuvTrap7BPHfn2e}e^CeyxhuwGi7DK=J|KHWXD zWz`BDfO=8OXv(ngWtR%V)fn&I%H+5KU7|Zm&=-eYY%Q{kRIi@oBxo!&Y?Mp3mSnLo zYl{4?#mHEXhILAKzJksaCm7~*@ST%dpzD>4A2j`a`^Afa1V^g_MxcQ(bag)vr+ZB_ zTcXL*u7q9Xcd)=1K6FpzNE7!Q9l17N6u#DFs%}@uLU^xIVX}x z#Pi_?p8h32oGG+~!K79*TU4mg0<|`%s59{jLtwlL5LycQs`Z;xC40JW#CFKk7S%Ta z)biIc7=sS-Dh!*V*BB{7njNSS3KasoTT!G&3nS18A@ zNykJk1hH*1&xkE+G7}(gi42+G#Rl_xzyjD;9FNY5=L)re zMBP*49RPdn)?|8chAUPlndcx%0m<+}6mH-liwS^T(@3kU=~_dQO%gg<@2L6fQT(C9=#!kG@v`?UZJKw zLnWsfTU>QN*G@0+=nWJdDmo-G@?dNt(JRPd1n?&3JeCIA8VIV@1G>A5<*qcU&xK+V zWJ(bff9DKY3UpSY0nfP4QM7o50tmqjZu9;`xEx}S^p!=_D}3juOm56(3sGk9y1`=` zxYbj<`T}-Lu5S6a8bGd6Ip!*Jt8j{=m}Orr08>V0ay+Ond8#?kz!aetTK2u1dX<=} zPm=Mu4V0*V2@!sYY_?G$aD7f$*5yNqot01_96kG{EHR|yc^gDuJ9}= zA)CiauZhnWVVV3vLk=>9e!>xyFB}$s(yLRhGwQv5xRQ&gz@vm3-IM*7JBiy^?~^Kz0f8A3_)-H|q%x4BT8v;RA}x|bsbPdj zM3z_t7c^ti9l)%rki2g&f?WVE33JHGBs@sqC_BVKJI?>b1~=C&i$7+x?{5eQU@J~s zXlTNG?o0|Ay0;N-IDWQUnWBJ)?+5KY1oc)AP6r5=2-lc^i-lCFS$v3rkAYJbECl#a zZ}=m=Kc*W3I7Zr>5BdP}CLj$X_^d#AvbCO0;oSp)wzJiG1Tki2^~k4khnSu+W&U10 zM}|4rLEy3b(iDrDwqHC(g;oQ+uxn=Cx{^Icm&D`1((p00D;vUzjScXEMlI zLn5YFb|mM)9Dy`sfr8%mWCz3W)c~Tv(BvRT;}86Tx{9+&*lNB$=`y=FmNjFnEvTjk zU$RKUxG*evE7yA_7k*_5fd7_qC7h%mkRmeKBXCc-2nrL>h6jg4Hj#m@VQ+#P7RNSV zKH*+fJc?ulr#hhRxLyF(mBeSUkX0Kz;yuNBx+XN0*;$oO4FNL=Bff7#MQkBPAf=3| z_#5*f*kyPX_;8?&;k194rGy&vWKdF?WpUk=q+9=%5ZN$izL8#9Arsha9w^?Jd6L;g z>lMLLna$CzAnz&Zf1-%^Wt9&0%}#-(B~5Gr%nR0|ik?FPU}NbtKB4;-bJFacO_d{ za6+WYQ=~2@TE8)065}%gkxyL;5JAW;HUnXn>sTG{fx{OxwMtQ`(U-B`GYrBPK|#SB zO)reg@=lZ;L0iD{!lmMB9IyvuvLTBN?y)JGVXkpPf zqzzb_+5p)hgjLg&2*SA&ByBq9DocA2)We`?T~XEG1=4TTQoc>jT2;S*>Vu&m8`}ey zeRVV0(jZM69zM-P-IZ0;HXD@_#>V^9_MGI|JNMM1m@JwND}al;lE=_oBq0G}$9v{w zANW^hh$bRG78*H@T9%x#c2#iLVVn%;q}IsiLe}?$*mXQs-3=@Up)-Z(kPM#9j>?{AEFVnE;!^CdJfnGOa@54YTUN&qTEwS4sf~Z10(21-G z-#fV?1TI5t0EwJk2D8fDdZ0Wih6esF*z}IgQAz_9bYVTj(gng5uj6bruL@woE2ovD zPdHTYr5K!_k5;n`2ix0QXUzqC*UVJr_x9zdb43EDNWu@y1e&;W!QE6oQ4%S*Ia6gm@q zOYE~Um;`X#MO-PSo=(Ga+5kJZtmz37M6Tf`9BcG6!4z{_Uw|q{)=)z<=|a(P^-f?G zC4ockcH)(37`c3S^d6GCN*ffej&~&y!st*12gwMUDv0OVHYQPuaLBC+3cmr(I0=yl z#v%i7+68RPQYDgduh(fTR_eaxF+_LbXls#I_$b6NLaG|JEC_;m9Eu?W(zG3a>54u^ zfr1ywb*fAhF#cPvR=0C#@IW{n$N;Jk$BxC$`%ceLstekvA~YJdOa?Ku2A1lc>eP0A z9iFj!&TZqAkselCGF4wmM2L|vkp<$)(D)&=;gS4QbLNFVsl*AgN5NXlVmn0TsclGJ zvJ{TNm5i&+)2^bCc#{9b-`;}cx1CHWIUFQE``voia4K|5%cYWq5nM^`ZFVqBq&{tk zh6O+blJeC~${JKFh;~s$t&4*Kh42YGkkKWfOs3$pY#`4GhRuxvEqG3RFmVNq1@S>) zbS!m({icFqc~M3o`&3(GeOi$CAz>kE-BS??%G80Z5gKN|sG8HDtZ_tp3#T>+^ojdW z42d?;J7NehnLNPt?Tp3TsE|A590^LTod2pag#blFK?j*(b6jZ@_RKhZxZoGY&Vpve zl+fdWIge7n%yg(L+OfAYJrIB8)x2-nqj7ig7T3HE5lz3kD1dUyCaZ`4 zC4-hiI8(ctve=VN(!rxPEmIc>0a%WB|bj5gzPRvVznZVFE zBu=ihBd(CuVIt>@VHZ0A8mMMUI(21+3>vMX=!u{vOCnKWB5wJ2}@ESATkV9FG)wb3HyAnc|HiWvC# z>MuyT=*7TN6j1BpEXnMSDB$V;JJZP!XU#Wi5}nq^Lp! zN@Zfgsr1r&bi}Z(1Sk0x;e5LknCkEu7N3Lhvab!Y|V1WNoXLewm`x zOuky_1V8N*kgJCyq*BpREPo%aL_ejrXQ4ss`h+aYo+rHDGdBT10gl3wFd9FJMKS@; z#t>ttfsOm!#JzUA%qCxO|^mSO3+?LhPdW(y!(p9O1 zB>@=l2$P^@pb%z18BcZ>5(Jx^zTENXmky!0*8dm)ynM3_21q=$n*kvvf7+IqE3eGSEnOU#qfS>oJbXeVz)_y*|pB92do) zHQ-Vw+Ivpy4vs#6gFHkCN>=Volw+McGIFpFR=T&x{|~rf6<~uDuDvog!p7pu*ty{X{#wG zYaKsP_nnJghN(+#z!%-~d4*lK{Q--k4IA zp_)Qpt4a>i8sHpI{-Om!sFJG46;_YWfl(l08bFAdTp|o*P?Mv|3N{@U5&E{vE7_fG zau|HCI2CE3NO$Lp@Yj)E6c&x^Mi@F>_QeSCHB|Z{c@iyxr;T*%Rp@0kPmNVdrGkM5 zp&P)_b5di87|H;V$ItLWAes_N47B0cZI}pbhQ{WlM0Tk&U=rP0K2(Fe4jxRgM63EG zOWCC8KW1TOI2#n$QO<)R>Rc73lnanJk~AQlIIsj%qX0ldiVMJlEnwSVW00i2iC!2v zI%W)EaWW42L&iUVhU1T8D{-roV+o|ptba0}D=97o4(1%NqO5GSh(M+lC;)L(QmRMq zXfl^e-$vco$<{<)>XeUp#7p2ipU^*3^vPiTN%c;iVPH2-=2yGC8A*VjT2dJeC((3xtE47qo~|tn3sML+8YY1?;sv~lA2C!~)Hp%x z!IMlny)?$gC=%w$6x7W_LD}1uuB6`zdezcoP!pIckWd(fYB4jflSJ;m1^W^)GJ^PK zAA^I9RDR*sf+}zk+B#UgR4Hu1=w*r0+Of9)$f5?nmn*qn-46-}8Xa((BIHA23Y@as zlzzuzGr&bscc?h3MBX$N(>K_xn)2_U)*ocY;3UKd7KQpuY~UtUFr>K>X9x>W9w?(B z99JToU!c*ez!>boH*5H$xl`TW>wazia+diX_fQ_qtdB9Uc+ zS{jtMFg#m0eaJ7|T0NiWY*M@t7Cw{77Cn+rol+^Izz2;7ak8ah@G+k#0CrKSU2obNDgmON_vE^rXx8Xh&`HEVrASeT2uEF=$IyjHZjQXTf{hXxyzQqq3#fo0dpZ|1l8=noOqFHk z_P8UJ@J2+B_#I_iYInU-%=hXX!5roz!N6qNIMr2ksFHU{eAZR-a-Cb=gqW#7b*?6s zMpf62kifc*EA1^;pi>>zP|5z4TA7ZDK?h(qQXHe`O8T68 z0ilm;_!Ae5r4pSfZ!!perscrF0v}?jLcX1fbrAL~nDWGuHWJRWh+X=V8oC29F8cYv}k2f}$H;K3FO zF!Lo09v>?Wb2v6;1<#NJe3G8dSjR8x}V4>`!=YA%N>d3^qZ5DHYP zCID~J73`AbPd@gj8PBC+vDAvI<?BmlGtIHpqlgKK>M>}|zP013r{tS3G9pI!1;KIg5>gHT_7AiYz$%`3uaH8* zx4^?$3=#{wqXH5$6iwf_xrQHtR(dN#sa}oz>PpG((T9wD;;AB|AsO1YZ9D>= zs@PM39;50cvnV+ZPE|-o8tXMULRD^IoMU(>Y3@13;uEfoc9I)vt zVkAYe50Qyb`&zrIdo>rBez+6P3{C zHSvq(zNgKUS7(MyhAAu>t*M3&oPreJJR~*_H^%E>0cy`zp3)L*;bYg}3uxc+NVTBN z+6Gg=1JOVQ1gq51D?}@gSR*eJ2=Pfml7hw>%GSQFFzyUUP%1l>A>$L8QRKvMH~8UG z{bYYB)R7-}4bj~~ssQow6f}Gxw52X}2)a^|fTzvgg}rL_Bi%0tEE*77(dW(LAsiyR zdz(OE2tZIeP{T96Bklz&(iAAEHgNE=L4XkP8z#FzO^xuPs1%B@N_`hh-rZb8H?Igo7&121h(&$UoPKttnW!l9HWrUjH!t zma7DpOafH0$%61V@11}`wRK{%2U%c318a(YHq3}QRIF&~1GZ|qiQs^)As}Vq)ieb#8nBs(WKE>OZ#9V9(;j4_3;aSMzZD~^ zNa5HyEUaYu<9nAGe}uzi#+ai}GE7%g&8ND8J073Es~-3h_Zk-EIl?p+RUshIz!JD= zh5!iNYUwXgUNssp>UV=T1DLX__{FzufqFX#=2|(^n2!G-W-Ntrj+t69Vw?U6$zgpMr6No{Qb0(=Hz-5&KVwny30m|4?-t^;RRmq6wH9+6sgm^ zik`SL*8&+AfP{HF0FM|TU&B1Ae{3YhPuf)v;20?dQ_}u3!YG=vya)varaJ2goJIy4T~T#sUmtLEW&eRpJhLQ%g`9y=y0%y zR9myG0iD9|(kxBV7PF20B;pp^6h+&F6F{B1p)9Q@QwKI=gl>?rZ1w|Tt^Yi`d z^?$>l*q!JfK#&9ytD!Ej9A@?W8apK@X-#w+NL?&x z(T8$Eq_jEHDEgroGf~;Xo%rO8-d%s985UXdJ*YwU`Z^tor>2- zm~k$uht%7c3%D6z02>l-=?mP5iqwEO@3TYh$0)-B2iS!>H}~k#MiP;FQ77LoWulHq3eBDzT4QhjQye$ zNM=V;XZhkuTW(4w#AK)xX%!MDxjuIbKE2eU0u=!LvE!nPViu)LAVMl9BKs6esDenf zrQp?wDW_z_2xC#Om`i;TRu>4~%Lcy0z3kgud7RHcF(4|RS_x(wRX!#J34x9Y!=fa! z!XP&VUGkggjV*E9vuM=JfZ&L07Ps+E@Um=^k3v@UZS)-Xq8q8m{}8upoP*UII8Hli z3mYvK?YW{Ujn*R99NJBcNfa8|$Kyu|LF>G$z!hMC{93_}=1z z169iidy#?i5D?`Dc&L1qe*{_pLrJVs>J3E1M%9Fr1c;r+8M~5NGv`2pBLKH*g$d9( zBW^t_!e*AsMkMJLT)JgQ=OYy?yt}zB9Qz%%vby+HG1F%`iLpJJclAR-3lChF2T=b} z`krqh%EKE`h&COV$sWwg(;KRsKluquA@Ep{48ua$Pw(jhzr;ycS!rSs6VntOP>xeO z-CyVw%bTOVZaIKJk!Z^z6kA)1oJ0kCK!XrtZ}84WtG=zt+-(a&rs6?&C}5=>Eyf|)euV` zD6qIcL|?*==^F~cek>!ptp&z4l}7;Os*}zcEK{H=x~OGuF$4`=*4mengC}p)#_d>FZ_y`&ezhbX~j79P z9X756!IQN7LTY{kAt|sb8nBW`>7!*^)trP-ySAL}mar90up|Z>p$ili_>;P`DPm9s zK|$dVy$_<9PQXGG3TuE$kl#lHZO~qL!G?}N>rjhrM{!I8098CR5EMA@T@vmM88#)w z&PNy9H|k)KElN&hJhcMtBVvg09Gx|_z#QO;Fy@m5eBZ$s9rSCB(+pW2s&L!u6LI?t z64>(65X=YHKrA>C@k|khe)7dY?4rJy2T^V+5T8vfLF1o!2uGYMl-En0Ee=L@I^osM zaKq5JCUw}L*vc#TY=Wt--+ z==U+%%$h54JLB*0o<|GGs6~-5NPF@I@!4v*^Jb`HP|zJ!o+XVu$w~uCr-|iA(yu$u zM;%)=;ffB_23o*lL9kZTn+Kpgi|_da!08&&H^^t4Uo_XuiH;^50hC~xg>4K5 zs-ZC}2zu#~1f^d~B8c)&4aS7SBC=hb;L1`jHnDoJ7aN#r2%Apji9D6kVSLlv*c}8S zQok7QN;Rp0y)u*_iO0*L>u&^GPeULC8>A_~Uz{tmtx-6(2Xy#(aObBJV$u|R-1jxA zM`SnJrx7x}r~}iS_DPqe5(31u;JF*H!}M6-$To6bRT50ss6XA4I2s#9b=Zt~$R1~I zwiW`}skgTq!2w%}K+0s@uS=~=;mYb9GbHKSY(Nu0w)Za9O6=K_oyhaa?nqHI7uwfX zGGGNVu5tuT{lAxk5<>K^sKj5`g0*%i?P6NR@?0r4us2@=WEe^`FB6@Et&B8%$fm%U zh@JCFs-uZ4HEq`)AvRT5Rs2{Y?;gt^jL)!OnnGZBum>NU986F4ToL971JNk_S+1&| zRUwLObmY~XmQ^`RX|FLvhf;%_QrI(Gn^Q;4Y}}hnh(;8+ENUAIV+1NdQ8k}$g`lyv zga}IU;b)y>OUP81HrY=?sG?wR?1j)lk}ad?2f z6pXE9GG@&Qv)xVcDspg%LYz26g)6xpfu>&wGuIqWM-*`eT)Pa@qObwi+lQ(Ea_z&U zKV=jSToUL0vcOCiHFG!b?`eJQs{<~sB-tt86TUJHids#k%tSE0u;ZjCna zhpnGD1QU|Hf$(ZVBtbX$c|FQZ-E-VNY7Ov*DuWEOHI*xvi@iYLTZXqP^rU|ENfTQW2jOO`^8bA9W*eSQvac z!b&GxmQ%+_y|0iEWM%fb!0RzmtLX#4gy<$BMXCv$TD_-!jU8V+$hJlzmQ?eVS$UXI zU7=1^g(803zDa*zl2D=^^ksY?$+y=@rtX8MJokd1c>4O&l_*(BtRxnGf-R!UG>w*w$8Tg?G zXVH=0u9V{exmrk2xhR$`STG;oV&ho$oRtMIRkMz*Mu2D@P#uHMGU2nA&hfVwRE(m% z{&Ktx7FV^;F~5)V^aA2yt7`6!9@w?YMT(bpaM7~l88k<#nRE=T?q<6!-8ij zju19@$VG0nRx~D7ozVgXB38@Y%s1inCBPzNqdr?kYQ29wV1m$IMuM@K-3F(?7T z3IcnfE8$p`fKsK~)IP`DU?oYij<03GcT^rJo~LmdL-gG;Jt2ES=n$0Wl3qhRAxYMEzdqk6el-9b2@N6uUdUCQ^ zx+ioP`F`w4epnmc*8|F&NL!q;plp(~)#k9jZEwrV7p?@k5&+}?OO4aT(=~+zB#tdn z3{qUs|Eys4BZ9^h{p_xegJ!d<8EADHP~vL}NDT&NxYWV_Zi!tyn~lsO?&&Sjhe#Z7 zPz_W;mkD?(Rji%rE&n3B2>R3+#KHJ%tS~}wLg8SA8b*umvt_-HI_G_D zU08==kpKi|F}ISeJS1g?=J4u7N)-1AAfSR*r29i3sDe904!4Lp&zRGDXgpp75aJ#J zrG68w=1)Yq&=rnlH%td!Y&#mXis zn0cY~ggt=%W~C@Bb7_%Q3c4l`V8jE#C4oJ^IMYd!3mOc^pU;eNoCge&U=NA;>h zx)s_`5uTkcA^@C2mt@H#gW^d%B5>6T;d$jkMPu{_k`mpId_{6S zpfK(-jx4H{ufa6$SyR$T^zdJ^##uzv4FYY$F%&)Z>Tk@vXle;KX2haqZBqH<2M7d@ z5&?*zljJoocqo<+V)0BcGYV*>Fj|5OiQ3t;mpmao9aNW~?;G}d0R=VDMoY4TQLh(1 zLSpH$A^7YG_E!g#*PtOdzO*ICwd{Lbh*+ST94Bw74uOC7M%W)&EUPu9Jfk+e1nY$i z6A4fmNHlP}3P5os^r0Z^2V0$*0j3JB5Js~0_MS?OTrDQrG15DvK@(A*eTZU?K2i!N zFD}&s6x%9Gaty-R(q_6BjA$Ato1u6nUfYGNKjI=vOrBBgnP|eiWx#;Rnek)JqYr`3 zU_TOVgKz15Wf+hvW>40txP0ot409rl=O!a@2k;cPs2}uVRv}C;eahr)e9}Pq~((|wzd3}uIR|9{3SY31J+SC0nHZ8 z22-FjIW$$lsZn2QEN~Dxku;iqq-8~!S1S_OzKL5pw+IGP1k zq*aCD_iQRf9M;Gwymh6dvARqXi+mQcNp!%0DboPJ44C=J(532QIgVMx>L<=yE-W_L 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

SzGUZSuZ>b~| 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 G*YzKT{5o6! literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/00/404e6179d86039bbc01a925bdc34ccdab778bd1d824f5562aaa319c6c8f045 b/tests/resources/testrepo_256.git/objects/00/404e6179d86039bbc01a925bdc34ccdab778bd1d824f5562aaa319c6c8f045 new file mode 100644 index 0000000000000000000000000000000000000000..8d8d1d8e82826ef293e6194fd62fe58b610a64a9 GIT binary patch literal 267 zcmV+m0rdWO0iBRBP6ROwMXBc$>9zvdiQ_mDLNt_gTp&*D-IdrKG|YL6N#fP{&9f?`+(G`CnaXJ-;gRl4TtnA|jaTt3=n z*F6BD0K$ZVZiHIL+~Lp@3%g0orO)8SWCrd*Y5>rsv~%Ki%}9 zua~EQv7}g#D2Mx550*)%o!$O>zr5OZwD21f4wS62%-3_1h&jb+T9u{~z>%^>08ZHb R5YE?q4eR@e%QrEBc<=pegz5kQ literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/01/18010feb81fe41b9df646d13866742a9070b56fd0ba9ab8dff828fc36c1f78 b/tests/resources/testrepo_256.git/objects/01/18010feb81fe41b9df646d13866742a9070b56fd0ba9ab8dff828fc36c1f78 new file mode 100644 index 0000000000000000000000000000000000000000..c7fbd7e9ec841a330674a2b7c4d8c938bd219006 GIT binary patch literal 205 zcmV;;05bo00iBOqPQ@?`1^MnO{Eu{%I1i^1La>zBaUh~;P@21cx(0qnXO1*7dT$Gy zu`g??!d`M_OM;?z{ zp0AIup4;(|(ci&3n{G2Ef>(paY&X55mi|-UK1+dXbcNauy`Y_I!1d(Prpg+#>9zd< HkoRAa=^JDU literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/02/df938cfb169b0b6ba0dd16acdd727ea9364f7d48c55afed2f7dd889804065b b/tests/resources/testrepo_256.git/objects/02/df938cfb169b0b6ba0dd16acdd727ea9364f7d48c55afed2f7dd889804065b new file mode 100644 index 0000000000000000000000000000000000000000..cdfafaca76c5125ec895dd2db23dacb7deb81805 GIT binary patch literal 103 zcmV-t0GR)H0V^p=O;xb4WH2-^Ff%bx2y%6F@pWY|ej>WVbXmdf7@IP_Uo6IJc=qbL zq|eXzbl+;$b4H&}E1;_Lb5a<#Nl)SGxmmebk0Gq-=z%#(tY)Q;ZmYb?_SQI4`tl&h J1OSNDCE&90Gx`7k literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/05/f7b70a01b0ade8afa5a5fcd19f12cc38faf337d10ec03ef4363d1a86f63750 b/tests/resources/testrepo_256.git/objects/05/f7b70a01b0ade8afa5a5fcd19f12cc38faf337d10ec03ef4363d1a86f63750 new file mode 100644 index 0000000000000000000000000000000000000000..b135eccdafadfd5a8e548e5fd10adbb00a8af34f GIT binary patch literal 21 dcmb003G-2nPTF literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/14/bd335f9d7188c778d44eba8801fe9bda46b66593291f5b9f7cd5f8888af12f b/tests/resources/testrepo_256.git/objects/14/bd335f9d7188c778d44eba8801fe9bda46b66593291f5b9f7cd5f8888af12f new file mode 100644 index 0000000000000000000000000000000000000000..58b2d0932a9a88359a302906668b00fe45deb1a2 GIT binary patch literal 99 zcmV-p0G$7L0S(Nt5rZ%c1<=% zX)_4V7#zcAAHI_HAYT~VoZUD`r`C;up%hMC36qMH{C!Zj^EjSa@~&??zHeMt`2%;? FAObt(FYy2X literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/17/9496410f66032c03bd2b7e8ddfc9c8c47820fab5615cc04d904989ce800498 b/tests/resources/testrepo_256.git/objects/17/9496410f66032c03bd2b7e8ddfc9c8c47820fab5615cc04d904989ce800498 new file mode 100644 index 0000000000000000000000000000000000000000..97157644b1b473df7cc6a9233900fe07123c0b02 GIT binary patch literal 64 zcmV-G0Kflu0Rc4t%Kvn7Wn~~VH2^U%Fg7$aATcgeZG}mfxK8yPV&{~SjE literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/19/0a1349522cc11f8682e34acca4ce4e1ea8508dfd77c24cefd461b65cead09e b/tests/resources/testrepo_256.git/objects/19/0a1349522cc11f8682e34acca4ce4e1ea8508dfd77c24cefd461b65cead09e new file mode 100644 index 0000000000000000000000000000000000000000..554d191b3aca70ffde00fcf101d4e9a9875cc1a9 GIT binary patch literal 92 zcmV-i0HgnS0V^p=O;s>AV=y!@Ff%bxFfcbvHcT=xOSUjINisGxv@lIgv@|z2F-}S~ yOSAwoOw27AHcoA~_Bf$(bLz>G#hz97>XR;=ZS4NsQ6BTFNcIU^-(CO?b{=3|pCc*& literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/1b/4b74772bd83ff28bf44cda9be93f4afc2279623bb5b36c9194a660b7623c24 b/tests/resources/testrepo_256.git/objects/1b/4b74772bd83ff28bf44cda9be93f4afc2279623bb5b36c9194a660b7623c24 new file mode 100644 index 0000000000000000000000000000000000000000..d5c518ecc8c721f8632f0bb8ea332f8a97a5497e GIT binary patch literal 236 zcmV_=Q@ zvc^JrmF}Qg=!O7r?zLNUX-aCt6-~5{l4I4ZRZTgp^D02}=TX1{#hFVf*erreuEopX zmDsxD7%`+ZBO8p_oyqEor3M02%1i&Am;Fd@zR#InF5UNQdi?U=@O<9-`^SUt+fzcS mxgjgmbPp9^xwW@vX8dQnyvA{kWJkaHC7tY`)A9qv31^C*IC|Ou literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/21/e1e1ebe45b2c1ef79ab050334e36a8015a546f0740bea4505e10d81a946f61 b/tests/resources/testrepo_256.git/objects/21/e1e1ebe45b2c1ef79ab050334e36a8015a546f0740bea4505e10d81a946f61 new file mode 100644 index 0000000000000000000000000000000000000000..31aa9e5f53d3533a3a8776bb36eae93699a46384 GIT binary patch literal 162 zcmV;T0A2rh0Tqlv4uUWc06q5=dp9B5rPwwx#t(Qi-n(?cDg^@7gx`zF9Og1pLJ!*E zVd9sx1xz%j=&kl*sF99h#|?KJ(7T9yA|cJho+8>>J5M5=#mML^N^Ol%Wt#=sDd$vF z+27*PY2?56vcMy?G8VXnr6f3)Fi!8!wa+09)gE0ylhciLbz|X(gs9a0nO4{d@RenQ QHRX8_*msrs0f5OkO$&%m&j0`b literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/23/8a501cf11a036f2f248008d88e14af624bb07fced6390997a0fa6abdad950a b/tests/resources/testrepo_256.git/objects/23/8a501cf11a036f2f248008d88e14af624bb07fced6390997a0fa6abdad950a new file mode 100644 index 0000000000000000000000000000000000000000..66dc15db4869b30415e10f5559c83bd21e1cc737 GIT binary patch literal 143 zcmV;A0C4|!0V^p=O;s>7GGj0_FfcPQQ83XfsVHGMvvq;(iZJ#=1{Vca|LU9;dT|3^ zs-}RH!xjCk)2ws<&o?mu0)=FTDBZA`{}!8tZ_!@aqqM!Vd)0!si&z)QtiQAU!B21Y x-LoO;Qc@W#_e&k>IsC&}d-?fyr?UV5oyGsmvBGyp?4#HG;oCzkG66E(I?6KoNm2j+ literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/26/149bf1ac4612f24b532ae50a12b15f26aace3718749624f008bde68670352a b/tests/resources/testrepo_256.git/objects/26/149bf1ac4612f24b532ae50a12b15f26aace3718749624f008bde68670352a new file mode 100644 index 0000000000000000000000000000000000000000..bee6a42d79b08c80d27f1ff7f4f95189f55eb8fa GIT binary patch literal 202 zcmV;*05$)30d>z&N(3~>FKgs_E z!mZY07>DpMx`cxEQtzPe1=EZwDosY5K@}CF97|2nW9;RP@0Itze E*nhHQlK=n! literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/2d/b6069c27ca4c08b784048644c307e17d0afe29b55f6488398cb59f13feb2f2 b/tests/resources/testrepo_256.git/objects/2d/b6069c27ca4c08b784048644c307e17d0afe29b55f6488398cb59f13feb2f2 new file mode 100644 index 0000000000000000000000000000000000000000..3dfd5463ba9d6f8014964d36504bcb9b30ea3e74 GIT binary patch literal 238 zcmV5HexU|FfcPQQ3!H%bn$g%Fn%Js!*p4}?iiagzF#cHYk2nR zx}?v~_;lZD)^kRmPb*9efIuNJi9xw5K<1+qbH2Vx1ILX%k@ZR58|u$pv*et<;8)h( zwNtsE#wHad<|Svur)B1(>XlTKFibnx&oupUFXNX@x6a;MqB`qUwr1jM4yC<1JoX8i z%nYtjZF#BXVCA{-mnQD!Pj~T~x!O}-`s1Jbv8On1ZSwhS_#jYl%lU(gp~~}fQW&;L oPvPphS-Dt`A*|`>fjLU7W~GmAtGvqg);Lr8@*u|q05@b{udX9}%>V!Z literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/33/e415b835a670bb5c3c760efa0433ac0cbd2d44679f68f2df3a9ae7014cf2a8 b/tests/resources/testrepo_256.git/objects/33/e415b835a670bb5c3c760efa0433ac0cbd2d44679f68f2df3a9ae7014cf2a8 new file mode 100644 index 0000000000000000000000000000000000000000..cedb2a22e6914c3bbbed90bbedf8fd2095bf5a7d GIT binary patch literal 19 acmb-^#q`YpgYeExCm$1-f;R9_b$X6tN&u7x8yM5P{8S!URcAHi)j E9%rINA^-pY literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/36/eac24505d4c4405864ccf2f30d79af178374166daeceefbf11e2f058d30d60 b/tests/resources/testrepo_256.git/objects/36/eac24505d4c4405864ccf2f30d79af178374166daeceefbf11e2f058d30d60 new file mode 100644 index 0000000000000000000000000000000000000000..df40d99affff9bac5a004388e3ae19ec0df19488 GIT binary patch literal 21 dcmb&K@VmFECanOevRMB$i#Rc`n6$Pz)g@z MiOzronCJc{NQdPt6aWAK literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/3b/58565ee067f13349cd4f89aa396d10f71c69e168d5c48ea23de59734ec3ab1 b/tests/resources/testrepo_256.git/objects/3b/58565ee067f13349cd4f89aa396d10f71c69e168d5c48ea23de59734ec3ab1 new file mode 100644 index 0000000000000000000000000000000000000000..1b299dc257b712a486bb7ec5bd07720d88001374 GIT binary patch literal 38 ucmbxW_qr}%a1XW>muA9bB#e literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/47/3a0f4c3be8a93681a267e3b1e9a7dcda1185436fe141f7749120a303721813 b/tests/resources/testrepo_256.git/objects/47/3a0f4c3be8a93681a267e3b1e9a7dcda1185436fe141f7749120a303721813 new file mode 100644 index 0000000000000000000000000000000000000000..711223894375fe1186ac5bfffdc48fb1fa1e65cc GIT binary patch literal 15 WcmbBQQQ6W+Sv9;eTEK4oHX{LN+y0Ic;3tpET3 literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/4d/f8ed86acaac5dc82b5652170996ce459d39e3a441e9759b635b0bc4ecc43fd b/tests/resources/testrepo_256.git/objects/4d/f8ed86acaac5dc82b5652170996ce459d39e3a441e9759b635b0bc4ecc43fd new file mode 100644 index 0000000000000000000000000000000000000000..8dc1932822c30e3289f0b6a74ce1d27f99fbca04 GIT binary patch literal 57 zcmV-90LK4#0V^p=O;s>4WH2!R0tHJm21zbq&mf(H@@-9zz0NE-=O?!!p!aY2A)ohG P61T;?x-bs_fTI)&EzuSA literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/5a/2d5699fea33657b42ba98c22b7898baaa0eda205a21cafdcb7e0f94b07bb9b b/tests/resources/testrepo_256.git/objects/5a/2d5699fea33657b42ba98c22b7898baaa0eda205a21cafdcb7e0f94b07bb9b new file mode 100644 index 0000000000000000000000000000000000000000..dd993131694c0525737a02638048b52c66a7e051 GIT binary patch literal 64 zcmV-G0Kflu0Rc4t%Kvn7Wn~~VH2^U%Fg7$aATus>cys_Z>cT|@)WkqoWX$sO4SBB@ WgLD>cuFmhj5#sPz(+yzy7#1e#x*6;M literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/5c/a8959deb2b8327458e0344523eb1ddeeef4bce03e35864640b452f84d26848 b/tests/resources/testrepo_256.git/objects/5c/a8959deb2b8327458e0344523eb1ddeeef4bce03e35864640b452f84d26848 new file mode 100644 index 0000000000000000000000000000000000000000..39e27c06a34d78ba0b5ef81a20bfffde58e1761f GIT binary patch literal 251 zcmVf|aRJYGoQ;%Sqm3i3k5g~~y00hw z_oXj=+b+ZS~!)xQv2m>l9OF3?YLT5R01G#z3j*9JMX{dB9o%3sXL+qUBuY zZmiZ*j0s)IkbpyM6}aTWR9hoQO?(vF5-sIE)_$0e`csZ-zSh3o`fgrz(noqfU&eap z7wOxZu`YR+EMhRvQwz(a^PQpp?Ju8toYnAAc3I8ocIU^*x0AW-qnm!M%P%Nua#IcE Be}w=5 literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/5d/bb1fff5c0094b31b25b4635ab9fbee66d65fe5dda47dd0ac5f01dd69a84c6f b/tests/resources/testrepo_256.git/objects/5d/bb1fff5c0094b31b25b4635ab9fbee66d65fe5dda47dd0ac5f01dd69a84c6f new file mode 100644 index 0000000000000000000000000000000000000000..17fae64f46499e2866d81cb0f67a7c8bed7a84b4 GIT binary patch literal 212 zcmV;_04x7^0d(`d(|t_|MHJ+=a$OWm#yT8HtGPUp2RxAez*A`XHW2JZ(yr55+R Oz^@1DuG2SS##aKt&t+!- literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/61/489e9e831f1d9001084d39b79f964c293db8620d679ea3596673c8a326446e b/tests/resources/testrepo_256.git/objects/61/489e9e831f1d9001084d39b79f964c293db8620d679ea3596673c8a326446e new file mode 100644 index 0000000000000000000000000000000000000000..0bece845b96b3be7ca7f12ebd967e1764ce64fa8 GIT binary patch literal 157 zcmV;O0Al}m0V^p=O;s>7v0yMXFfcPQQ3!H%bn$g%Shr~IVb&{rX1bqZ?C-q|W%?Vo zv1vWy_7YyrDizns#zlZq1ak~8AdGILV(N-9birXB2On*O+#@yn)LXYVaho%JeP zGx0Tt(q0`N`vgs923M%Iywq~Aa_@sq4IM2{ir(cMHr#0REbn7~n6Kme4WSKw2k&aU L-~1H-4}m~Ae2hy! literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/6d/5fd291bb0f67444e99ab492f1bf1fcdf5dca09dab24cf331e05111b4cfc1a3 b/tests/resources/testrepo_256.git/objects/6d/5fd291bb0f67444e99ab492f1bf1fcdf5dca09dab24cf331e05111b4cfc1a3 new file mode 100644 index 0000000000000000000000000000000000000000..112998d425717bb922ce74e8f6f0f831d8dc4510 GIT binary patch literal 24 gcmbBwx}Rd~@4XFW`Wv>f zX+7ii5?;+J71zneN1>|oQp@#9DoPl<4>~n;v^*(#mvh)~qtUaxkNsi3j_)^wHuxR9 NtMPvGR{&K(Dn}t?GcEuC literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/73/8ff86401dbc5af692c83e660a4d510603c3f36e782a1a32ebd0388db6411ed b/tests/resources/testrepo_256.git/objects/73/8ff86401dbc5af692c83e660a4d510603c3f36e782a1a32ebd0388db6411ed new file mode 100644 index 0000000000000000000000000000000000000000..4c973ea83afb1efa8040be2204a65922df718df6 GIT binary patch literal 181 zcmV;m080OO0iBOAP6ROwMX7U&^hn5d;v|+3+6z!|g4l61Be4t`viIMGBhY-k;=SVA zalP&>8mP{?jXCQ!Je}|U;BMlVp*fLKANE=x! literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/73/b4f3c4f3182e6c8dd2c98aeb2c7811556538e7673e4b325307c71685fbf5b6 b/tests/resources/testrepo_256.git/objects/73/b4f3c4f3182e6c8dd2c98aeb2c7811556538e7673e4b325307c71685fbf5b6 new file mode 100644 index 0000000000000000000000000000000000000000..67b84c462af40737559130399874eeb4b77a3873 GIT binary patch literal 108 zcmV-y0F(cC0V^p=O;xZoW-v4`Ff%bx2y%6F@pWZbw`lHR)+>Bwx}Rd~@4XFW`Wv>f zX+7ii5?;+J71zneN1>|oQp@#9DoPk~<1bCz&7bb#H*>Y8zVydG_hV0S-rD5z+3-Q2 O;Fj|T7Xtu2R4DnfG&Y$4 literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/7e/4633ae1b0e83503dbea4417f9d5ccaf22b877c5a4522b6d1d2b16090ee2f6f b/tests/resources/testrepo_256.git/objects/7e/4633ae1b0e83503dbea4417f9d5ccaf22b877c5a4522b6d1d2b16090ee2f6f new file mode 100644 index 0000000000000000000000000000000000000000..993a62b1637039118d63bec43013bdb924745aa8 GIT binary patch literal 141 zcmV;80CN9$0iBLp3c@fD0R7G>asg$xn`|nG2p+)`sd4(!0hkIsFwuiRDb vbB?*M_O|CAJf;?x_a*msw>ShM1{&F(Apn@e9w#dQv_@suWu43yI6^)tb_75M literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/7e/9424c06052ca33bfc599bccadee60065d8664a9af7648a1455100c4f772e1c b/tests/resources/testrepo_256.git/objects/7e/9424c06052ca33bfc599bccadee60065d8664a9af7648a1455100c4f772e1c new file mode 100644 index 0000000000000000000000000000000000000000..70bf64e16bfff5cb9681936cc39fe61bb5114434 GIT binary patch literal 199 zcmV;&067160iDl5Y6CG0h2gH}6xtVpEom$pLMUCe7btXT*)koHnF)gfJ$_w!gKq!D z_jqMr*QEo-`Kcdf5MA;bVyG6ig(TJjVXZkSc}We~C-H(Z8)>WP=2^)R$5d5YW|{8! zu&skvR$&p;8mToL8guz|EK%d!3ZkTdq&kF9l24pNa4Mq}wUf|sJ{l&iXdcWDJ?CS+QA;q!A1kcVpH;p=Ob^A9ky>Clj@(uo^=?74V=y!@Ff%bx2y%6F@pWZbw`lHR)+>Bwx}Rd~@4XFW`Wv>f VX+7ii5?;+J71zneM*-?j6Xp&B8|nZ6 literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/81/55958bbda08eed88c8ac908dc44452ed38911cffa54ccc06076f30a1ffb1bf b/tests/resources/testrepo_256.git/objects/81/55958bbda08eed88c8ac908dc44452ed38911cffa54ccc06076f30a1ffb1bf new file mode 100644 index 0000000000000000000000000000000000000000..e610e3be8a17b7969705800cb1c052bd09230ec6 GIT binary patch literal 108 zcmV-y0F(cC0V^p=O;xZoW-v4`Ff%bx2y%6F@pWY|ej>WVbXmdf7@IP_Uo6IJc=qbL zq|eXzbl+;$b4H&}E1;_LQp@#9DoPk~<1bCz&7bb#H*>Y8zVydG_hV0S-rD5z+3-Q2 O;Fj|T7Xtt@NhwLRz&0BI literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/90/1505c3355518bee35475c5d3f23bac1dded688b2bd314cc32b7f157e100724 b/tests/resources/testrepo_256.git/objects/90/1505c3355518bee35475c5d3f23bac1dded688b2bd314cc32b7f157e100724 new file mode 100644 index 0000000000000000000000000000000000000000..09d0abfa7b4148e0a699117ecbb719df9669a34e GIT binary patch literal 190 zcmV;v073tF0iBOgN(M0ugnjNQdI6E s_g(HEPdfK!AAxd>sdDy@fkJSXdp%nApRQ}C9J=|x4L=WaKUAz$g~4B6vH$=8 literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/93/1093620e5f050e2127fb0b96786ebaa9ee6535fb698ec01b5f7a800fa27cbe b/tests/resources/testrepo_256.git/objects/93/1093620e5f050e2127fb0b96786ebaa9ee6535fb698ec01b5f7a800fa27cbe new file mode 100644 index 0000000000000000000000000000000000000000..70431af8128d71fe97407bd3333bfd6953435891 GIT binary patch literal 137 zcmV;40CxX)0iBLb3c@fDMqTF=vlk?jO#VQ`3%K$GnaPv}EQOlh-|7+Ee7wbb@X5L? zeE{Zs8k;Iaov<*Wb3uZSWkNwqjY7*U2c2qR8xjZ4NK9O~_|jUUrgHcWP2I=5Zt&ks34~NnJYDK-@s& literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/94/ed253efa9e86fc636805c294c441d08b89b455903c0c14e9b16587fec081f5 b/tests/resources/testrepo_256.git/objects/94/ed253efa9e86fc636805c294c441d08b89b455903c0c14e9b16587fec081f5 new file mode 100644 index 0000000000000000000000000000000000000000..41bcd18afbb47ff313b90874fa27decf3a34b5cb GIT binary patch literal 188 zcmV;t07L(H0iBQ0O$0FvMETw-(g4VD5<8I)x*s~A0Vj6Ylh_Mda=P{jE%5i|Nu$xU zaU9p_knw4rW)4t$3Ay#^sZ^*`1ynsrQ)Oh65-4`om|IHHO>qUyxnzhysczqL+HE?v zNFj*%3YJ5Hpw%Qs&%J1BO*&%D%q>Yw3rW4=nuG#o*r{)FpZhr7yFTPp_py)TXWZPY qE&E58&+FXp^`(vD&3WX2M8%VP1_s!cU9YD7x4(@q-F^W(?^Up9reI0hYPWM?<@LE8o(K`PkZiyW2X8cRHOfV>{BnkIcb` X82t2c`iq#_jy^W?S6Y4mjhI&pAZBds literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/9d/aab17c25f647d652c72c8cc3cf4602c270a369beebc7d0b67238897bbc426b b/tests/resources/testrepo_256.git/objects/9d/aab17c25f647d652c72c8cc3cf4602c270a369beebc7d0b67238897bbc426b new file mode 100644 index 0000000000000000000000000000000000000000..74b8385edc1e4b593575b40d3dc31517f86e9b50 GIT binary patch literal 198 zcmV;%06G770V^p=O;s?ouw*baFfcPQQ3!H%bn$g%Fn%Js!*p4}?iiagzF#cHYk2nR zx}?v~_;lZD)^kRmPb*9efIuNJi9xw5K<1+qbH2Vx1ILX%k@ZR58|u$pv*et<;8)h( zwNtsE#wHad<|Svur)B1(>XlTKFibnx&oupUFXNX@x6a;MqB`qUwr1jM4yC<1JoX8i z%nYtjZF#BXVCA{-mnQD!Pj~T~x!O}-`s1Jbv8On1ZSwhS_#jYl%lU(g0jN|@7j_h8 A$p8QV literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/a4/813ef6708e6011e8187224297e83e4a285f58bf5eabb1db270351388603c95 b/tests/resources/testrepo_256.git/objects/a4/813ef6708e6011e8187224297e83e4a285f58bf5eabb1db270351388603c95 new file mode 100644 index 0000000000000000000000000000000000000000..2419974cbc27d6c1afe3e38ab5a7b41ee67782a9 GIT binary patch literal 244 zcmVj1=F9WRbosttAR+ya|(cx z7H!qI3QFrHv9V~+$!AGYqzQRbni&u${T|DHgb&-t2yctpzJ=$z{f5`;s<+Q4+t-&6 uv7{OkAcaRL0Mkj&XNLc$JH7jH_0SI8YzdcD@2BSyZrj*Th|>?YL2LiRRDL}G literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/ab/ee32b3339d1566d75613ea61f40c14bdfc5b101b60fde4f44b58dd06667640 b/tests/resources/testrepo_256.git/objects/ab/ee32b3339d1566d75613ea61f40c14bdfc5b101b60fde4f44b58dd06667640 new file mode 100644 index 0000000000000000000000000000000000000000..b390250e308a62f1afc44c5f8e99e8196c1949ae GIT binary patch literal 63 zcmV-F0Korv0V^p=O;s>4V=y!@Ff%bx2y%6F@pWY|ej>WVbXmdf7@IP_Uo6IJc=qbL Vq|eXzbl+;$b4H&}D*(}y6gC9)8?68U literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/ae/a29dc305d40e362df25c3fdeed5502fd56b182af01b7740d297a24459333c5 b/tests/resources/testrepo_256.git/objects/ae/a29dc305d40e362df25c3fdeed5502fd56b182af01b7740d297a24459333c5 new file mode 100644 index 0000000000000000000000000000000000000000..18a7f61c29ea8c5c9a48e3b30bead7f058d06293 GIT binary patch literal 26 icmb$LsN-!RO3 zFj7m|IyiPuy{Urbv$bqx<=~cOoiTD0njJ+?vrLXKVe&XX+L^D=bRR;B3;pHm7;dm)w`+SyKUctJB*iO6>9B@H2 zqaBaBHh4?lp(XgpwOsGC4&yx?FI&&I_|KE~ym~}8cpAKkE$ouv&jWQ=^8>F2SAlTr BV-)}Z literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/b6/1b940a8cd979a32e005682c5c09c22053675e2db24ea6b4b28cc75e9c10890 b/tests/resources/testrepo_256.git/objects/b6/1b940a8cd979a32e005682c5c09c22053675e2db24ea6b4b28cc75e9c10890 new file mode 100644 index 0000000000000000000000000000000000000000..b1df3bdd5cf408c6a576fa3041938b194b268734 GIT binary patch literal 37 vcmV+=0NVd}0ZYosPf{>4W(dj1ELH%b#5{%koD_wmqQt!93`H&goVE$TEmshD literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/b8/3624f6ac0995273c0034a7ab8c68929bdc91b69ad54ef94979b93eba3f6022 b/tests/resources/testrepo_256.git/objects/b8/3624f6ac0995273c0034a7ab8c68929bdc91b69ad54ef94979b93eba3f6022 new file mode 100644 index 0000000000000000000000000000000000000000..3e36331ea660f96ddc6389c51c0b5b04bae31f94 GIT binary patch literal 190 zcmV;v073tF0iBOqN(3j0%EkJD$BPXewzWa z!-|SjiYX>T;Sx)U;<=r*<^V|U%o(URa?V)6q-3Ma8tbC>xs4-y*qAfCZ))QfUVrR& sTt0Wbe!bY(-$G1+k|I$F&maKHNzX^q|Klzi`nVr+3xAd60TLfo5g`3pC;$Ke literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/bd/f2066a28e11603a1af04157ee4aad97814279fe500340eb3465797cbd3be23 b/tests/resources/testrepo_256.git/objects/bd/f2066a28e11603a1af04157ee4aad97814279fe500340eb3465797cbd3be23 new file mode 100644 index 0000000000000000000000000000000000000000..9bb5b623bdbc11a70db482867b5b26d0d7b3215c GIT binary patch literal 23 fcmb4WH2!R0tE{b2HziV+t#c)dZ%e?s$#*+oF|c&=UKVPO^@7W Px?zvs8Rx$M(km5$Qz#fi literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/bf/cc4074ac517ed24d61b0aaa96359f304c3dc97e95f336269ed474ea846ada5 b/tests/resources/testrepo_256.git/objects/bf/cc4074ac517ed24d61b0aaa96359f304c3dc97e95f336269ed474ea846ada5 new file mode 100644 index 0000000000000000000000000000000000000000..be8b99bba80435c6152a727a07b56daeefda6569 GIT binary patch literal 198 zcmV;%06G770V^p=O;s?ouw*baFfcPQQ3!H%bn$g%Fn%Js!*p4}?iiagzF#cHYk2nR zx}?v~_;lZD)^kRmPb*9efIuNJi9xw5K<1+qbH2Vx1ILX%k@ZR58|u$pv*et<;8)h( zwNtsE#wHad<|Svur)B1(>XlTKFibnx&oupUFXNX@x6a;MqB`qUwr1jM4yC<1JoX8i z%nYtjZF#BXVCB{kVQ~-AKN@?U_3vC|nJe&JCi7v&)gyh2Y@bdyd1JK^0G=>TfAl9| Ae*gdg literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/c2/58f010a08328a29cde33411d955520e0375fcbbcc14b7636a70f7536c32ef6 b/tests/resources/testrepo_256.git/objects/c2/58f010a08328a29cde33411d955520e0375fcbbcc14b7636a70f7536c32ef6 new file mode 100644 index 0000000000000000000000000000000000000000..9d2ceb1fff9a7910b503f0b56ef465b4dc2513ba GIT binary patch literal 148 zcmV;F0Biqv0UeCN4uUWcL_PN__HJT!OIu1}j6dMbc;D8gq5=ligMTlOnMq#e@RSQs z2)i*oB`a8xHA$RLHj}hvAzmI@&G0Q+@ z))k6OaO<)R3KyQVgQM~=zP{(ubN4>vu|EOXNWPBFA?(p28gqSgGc4uJvq}GL_%o4r CbVjTI literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/ca/31f7336e882a233a2943787c5e94ba024ac9a4f763cb1d9bfd8e63aa7f7269 b/tests/resources/testrepo_256.git/objects/ca/31f7336e882a233a2943787c5e94ba024ac9a4f763cb1d9bfd8e63aa7f7269 new file mode 100644 index 0000000000000000000000000000000000000000..cfcdac3069711e3c0e4779477c932e2e4dea8d59 GIT binary patch literal 182 zcmV;n07?IN0iBOAP6ROwMX7U&^hn5#9Vd|x+6z!|f;e_GBe4t`viIMGBhY-k;=SUJ z<9gj!Oaf2qbdTZ_n=+=9MLKjX*PZtCZX kuRjmE{LagMyhS9gML1QC&yWDZ_&c=xA8DX)2hjgc&6D$5qyPW_ literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/cb/282e7c15fd8aeb2265cd621f5a228cb33dc84192980ca426cf9ab2a48cb9f0 b/tests/resources/testrepo_256.git/objects/cb/282e7c15fd8aeb2265cd621f5a228cb33dc84192980ca426cf9ab2a48cb9f0 new file mode 100644 index 0000000000000000000000000000000000000000..77d9ec27d546841923f4d7688b1675af7e8e4d09 GIT binary patch literal 187 zcmV;s07U014!Q&1J`S7%pUi!~ zFHa>stW(ujOsS>X`(UW5qgJUb4eF2>VWG)N3h{_=-}`0|#}?&_IpZ=o@DON9;t+k5QzLE6aaV8>(SExxQ>sxwoCnsxF4}jRtl?nS=|5t literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/cc/b5a03da85607c230d111abfa899655d1b00e6529101a40d42f6acb059dff9f b/tests/resources/testrepo_256.git/objects/cc/b5a03da85607c230d111abfa899655d1b00e6529101a40d42f6acb059dff9f new file mode 100644 index 0000000000000000000000000000000000000000..a67d6e647ccc1f3faad53aa928441dcf66808c42 GIT binary patch literal 21 dcmbpMgKkTOQrw- literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/d8/8b60d2641df3656381dc8e201abb820a414de03eb63c065b06a2ab37d3f5ca b/tests/resources/testrepo_256.git/objects/d8/8b60d2641df3656381dc8e201abb820a414de03eb63c065b06a2ab37d3f5ca new file mode 100644 index 0000000000000000000000000000000000000000..6845087e53a55683396e7a21bd3e5bd903f036fa GIT binary patch literal 171 zcmV;c095~Y0X59QYQr!LfZ?6}6zX|Ul*o<~D5KEp)>jC!BZstcG*b1jw_h(k{(SHo z&(QS4ho+lk10wNFNIeDaBBm5F<=CMVMo+{UbDG-8`z{Wp>q|Qo;(;Y%<8x`bclP%y zkXB93UT5AmH8z>XSB<9QTV~l|d#d9J*y$E@`W8X}4qeF*T0 ZEuwSZs(1L|16&m@TI*s5_YaNOJwhO_Rv!QW literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/de/caff3051968d1f3a2defd3d4a80ced03101555e1fd8913b3544026c0717d4f b/tests/resources/testrepo_256.git/objects/de/caff3051968d1f3a2defd3d4a80ced03101555e1fd8913b3544026c0717d4f new file mode 100644 index 0000000000000000000000000000000000000000..a53ab84cf2cf192d60d700ebddf789a324787ee2 GIT binary patch literal 181 zcmV;m080OO0iBP*O$0FvMLDO6GyqCsj}uD>twae_U^_9p60<==wtq&H!0qWh{lmAp z@3$2T<)?Lw5xq!G%^L|QdS~f%8-3dbn}R9Q0Bmk&<*ou<3B4LSp*E>N;aiSzUok6c z#afH@2JWS)BU%^M!Qd!vrBtQ@s+$5CXGS4PT2E&MgFM!C9`VEGTJilVHt+HE$Nu2* jxy$YA#peDNGvvYuR46{Dno>CJ`Dl&*Y(w}3o8?f{IrmoS literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/eb/ead5965196dfaeab52b1a5d92b78e54493fdaa78f72268d4cc69b61d5feee1 b/tests/resources/testrepo_256.git/objects/eb/ead5965196dfaeab52b1a5d92b78e54493fdaa78f72268d4cc69b61d5feee1 new file mode 100644 index 0000000000000000000000000000000000000000..225c45734e0bc525ec231bcba0d6ffd2e335a5d0 GIT binary patch literal 21 dcmb7v0yMXFfcPQQ3!H%bn$g%Shr~IVb&{rX1bqZ?C-q|W%?Vo zv1vWy_7YyrDizns#zlZq1ak~8AdGILV(N-9bi_I_f^(s(Gwyl_2>Xx)=lH!DQc z=RajI;oIyMKK=CNeacX6d8y@K<=zLK8ai5@6urwiY`D?rS>DI~Fki>_8$uiW4&K#x LzxgWw+t)xa*56Lu literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/f2/c8da1a7c2eb49ff25c47441f0b3f387faeddde1b37d0ad2f3f6a63f5327978 b/tests/resources/testrepo_256.git/objects/f2/c8da1a7c2eb49ff25c47441f0b3f387faeddde1b37d0ad2f3f6a63f5327978 new file mode 100644 index 0000000000000000000000000000000000000000..04bf5eb0621c5e6a453ac232bf04198f7a6a04ce GIT binary patch literal 192 zcmV;x06+hD0iBP*ZNo4O0Q>e7TA&4KQIrG}ML*e~3s52%=V3c=6=eOmEA)3b;2zia zb-j%+=lV7dv(UVEf=tpAX49FJv4MzGj;VSC>QQ^mR+GobGgni}WKxJlB~5oZY#RX( z3m~|)f^LMZsxz@-EX7v0yMXFfcPQQ3!H%bn$g%Fn%Js!*p4}?iiagzF#cHYk2nR zx}?v~_;lZD)^kRmPb;9RlZq1ak~8AdGILV(N-9birXB2On*O+#@yn)LXYVaho%JeP zGx0Tt(q0`N`vgs923M%Iywq~A^4$1K6L<5cyZFsq?Wr&Q@z4F(Q=GRp`Fu8f5Gc6i L{K3Tl{;EGa8DLRL literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/pack/pack-b87f1f214098b19ce092afb9ef6e7643653c03e7f91faa27b767e3eb8225f0f6.idx b/tests/resources/testrepo_256.git/objects/pack/pack-b87f1f214098b19ce092afb9ef6e7643653c03e7f91faa27b767e3eb8225f0f6.idx new file mode 100644 index 0000000000000000000000000000000000000000..897e8a478fcd5da84a4faf07f1d47e873809c40c GIT binary patch literal 1336 zcmexg;-AdGz`z8=LlH0n9gPix{4*FaGtgb6ViusDfyAsp`$sY9VZa6qw;_XdTSbe? zt)5tGZM8A@8Pr~PYgJ!anh zD`si9^@YFJi=Vu@&DZ9b?P0GIaKf^6-s!gAVT%eEF>R}PI?XA-h^~1Nyk|gsYf%8$~m*)2`Jr>GVb$z9txX6d+H=mR&5mLJN9RQC) BmmmND literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/pack/pack-b87f1f214098b19ce092afb9ef6e7643653c03e7f91faa27b767e3eb8225f0f6.pack b/tests/resources/testrepo_256.git/objects/pack/pack-b87f1f214098b19ce092afb9ef6e7643653c03e7f91faa27b767e3eb8225f0f6.pack new file mode 100644 index 0000000000000000000000000000000000000000..9c8557886c820187eb37b4d68a70c42aeaccc895 GIT binary patch literal 569 zcmV-90>=GNK|@Ob00062000J-5qO-Pj$uj!F$_lk&nbEVB~6od3bF`$1W%Bpsk`WG zWwzq=9rXtO`*`pk-`w2;wv{6nEG3CkQdEV?l)4M`l%YmOG|C22jVfvL#-^!3PkD}hK!yfe5D3>oHH~qFf%bxNX*MG$w)2I zE2$`9h_qJIzJA~cZ{jp9v!5?#m@w_{_Kt{3a$Qm_CS@pT!EOlAQkp9Tt4u9XNX*MG$w)0y zNXyJgZmc$_QGNGwrE%gjl&=K=s2`2)UmErk_wcRJ)dE3lPA{-pC@ky0#1 zz^TNPz3p7H(DMS}c$`Z$o?r|B1B3xwxPKoZK$x+d;F7Po?{0QOWjq7t`5&q$w`b$) Hf+g_whLjGt literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/pack/pack-e2f07f30db7e480ea84a0e64ee791b9b270067124b2609019b74f33f256f33fa.idx b/tests/resources/testrepo_256.git/objects/pack/pack-e2f07f30db7e480ea84a0e64ee791b9b270067124b2609019b74f33f256f33fa.idx new file mode 100644 index 0000000000000000000000000000000000000000..9e2ec99c546e6de5f8279f1abfc0f254565d625b GIT binary patch literal 66216 zcmXWiQ*dN|fQI3uW81cE+fF9d#FJ#gNiwl*Ym&^w)<3pw+qSJeyR{cj^+n&j_5IH2 zI@Q(v<)UH+1_lNKKmp(Zm;ihLIe;F(0T2bq0OSE$0AqkTz#8BV@B;V(LIBZ#ct9%P zAD{?O3aA6L0r~*LfC<0?U<e?TKR&gek07L)^0385m1#ts-0b&42fD%9rpa(Dk`~WxsTmk-o zFhC>#*boG42+9EfjUZr0P#FN&@&B{{uRtpZXa$V}W&z89b-*s*7;p)=2fP4)UI-`v z5&#Q82mm@Er~r%rU{eS_fH(ly6G9oF126;tdqP+P909hi061&N20#a305Aqv1Z)A0 z05<@j4H9UBf&c(*P{8>@p#yLMBmi;%&KoTGWkP9dVQ~;_0z=lx3{Q}hu7z9iKfKI4Y0MH5r>Ms$6CeN(2LQd$N&sL_Xag{q{eOOniS*{4BS|pv zhvtYT&6)dNLz zEUL=P(ReDu#419r5?L{eio5%4a`VA)ygEH7AhT!|v@a5vTts&h^;h+H#2XFP@2n(I+Vs3)x9>t=%uUU_oq`eK8hY&P` z5?k|{1z3-u5q!Wl!q$M#rCv2A)ix$n7Fiuqgev$m+&6g5ziy&5E@_3Aw)_F17NnEN z{6tDm%-&qoSL*(<5P@~;H@=Rv_arj+RGuB`DQY)U>3zDSH5s}DgwZripv{4Ukp12efWCc~@^Im_!16$3H&+px86*vOy| zN}^@vRk~K*7DC8JUgIhPg76HK7{t($C?j+5f)r3JD4y77SDzouqn~%x?ONz2V650K z-HubL6WX4F7>=@@>p7h-`Oq9;&3c`#b*Sby}&j$$!F~y!WC#`HGrsD6L*sTdh1! zECvD1qkS$q*$E~-XtmL--!Cdh#RuP+wHMbF;YN@_cLX7Hgi=!7<1)jUzqRTa{JTMQ z9UVLaavpbOy6yLp0UCq_YjVN<3}{TbU^c68#%Chq-(rRjynSJOlM4sG{40c4y{Hv4 z6w#Zx8_h;4I^6uiqaGV)nHF&-`R2dgjW3AoYl?r)^ZlFaG1eU)kSPYKCYA8t*%y*= zUiVgt4jmwRv-IKUX@+L0G*;VQ6gQww(-Svsz`dHzDx>EDikTsa53K9Wqp9*;BlNEi zv1(7Ou*JkT4)&T<#H(6MYS$o1aKik135$N>n=6ajj++s4xXjIcp{I(_H0ABDx5PoJ zbPT-0B=3C&^p9C_dC>ckQ(mElaIEYvDvh&vJkda^O8#gYSam`ABHn2yGgmzA;|InK zHI*OfafAoc0YTdLLq9TJo8Ie>mV^_=W0~pdE$r`I8Yw)3?kHP%zbzxRw!Lz$swLqQ4D1i9-An}$)+6aVqv?Buec(pE5r=Hl&| z0$-HAUWO85#n*B*;1cE_zwD&t!bZ`F#H)_5w5|qDSHp>remM zX`SDWbPy`NrJxA5jidn+f(0}7mP}|`uGwGe#v4Z{SFptp6JHLkkde&9cl(+04&RRs zhW4Ska9-p(Br)Ahi_e@<-w`S%9tXM^aR)GUhwgBeAu6G{>**LimT2VDyc?hY+g!fG zIwhEh>D(ISNmXQ?n+|~%zxZp#RYnz}7{6=j5h*K?$g=m#29k;v?wGPeG-(#vQdhPx z;6SE=XgH`&zx>+|mOiwn5+6;oVhix|R?T;4xAq)z1y3jh;qWP+<)=5yICZS#qInD! zNU*k|+SMQ!xLxSqTbKW#i@!X*()jk9zjZa(v5NRZ4;>=LGVJTXkZTk5t2lDGtzNH7 z@IYxFo-FeOw@4|b7gO5jZn?( zjJ19xWAi9liOS;vMjP+@-J?RA65FkcNBOp4*|uDqt-|l|{N>}x@ebEH7$e%K`dY_c zVm+-a!RmAWUpA*RoPn8>+b{F2`l&XQFs7iT*zh{LrhNt_$wBlizXQ zDL|e<>n>A^4%T-AC=g!%V4|wOC8(5Z1=FODpqz(_U_E-0LlQ?8%7^!hKxO|^h3O+u zIJi5H3mmHanJ~5mQx#_0#3~jqWd0ddVcs@o53{~$;i=>=Jxym?|6z5hZ`14N#B^x0 z%ZN5334MN@2#XiR;ciS^odRE$xrt}8qsD3S^pp{=XJe`>eRjJR3(I?&-S(DXb(%I; zmr`TXelViOYo{r<>?NqOa~j<>3oFPFC8;Gk<8)MJ>4m@!<_P^1>V(RE)=bAXUX<0N z4=ebrtUT-+^Vk-B-*BP_d`7l-MXy6B&5-BffNmBT#9S#HPsfbPB^mQ(=qYXX~8*-4u4kZKW+=?-o;ZugreR!$=jEh>4tjuBpSv$pTJWX0}g^M{S zPkGtsd6DMH0^oH*vjbvlZ0Z}o6G~fYuJQXKu_1@OJlu)if5iy}SHlN`?G$efM)8gu zGt@7tBHwxWRSYnABE)8Z^Q_~ApUNM^j~!;ZN#T7@d?k=vL*Op{}ak;c(IsURq7 zEa9W!Hv(!bT3png>OC{Ku6ISL2#w=QvM$06n&z*1Tj5(@K(e=dFIKbMnEuCTxH`^6 zlt_msw51xJF9j*k4Dj=YZIGjsG%o!tO3p!WirHYeYgFXQ{kyel40F50dhn;>C^?e| zJDwKSs0T$VPK61#ZSoPkaM1pVdekfpXz*9_zgG_Go|j z;?N9ZA>r?+^p>2cL(76uISu}&P@RO;wGzdo9Rs>?nHE88 za`{~jM<6sBYwVw6H@5e%aJ4tWAU)nLED^CEwHt!1qJnO;IC48dj;M-8TZQg$1{qi> zOM~{JN0HG_uLXpR*(L$){rTV1sU_4V?9f`bha^Nl&>pPITXLA#2@DZx3q$SX`fnL< zxI*)$Z}S&RiDKuMAKxX4D7WN4!R8Peh9uUIl&|aH0uzbdKgC0ZWKTJZN^!be;CmN; z-v%HosnR2N^Deo-c~oX)lchfrsI@=olTu|C+6Nn$4hJJVpV-g_M(u*%CFVUZpv~7T z2d1t$*_n6b1pX+TN}xxCx7UXt-+3VB*XY{=9`*j(Oik~-Op$v{Gn;H&&4VMVP`msg z>gtjV(?vSfx2;bxcVeu2=H%prV_Es{3LXVfQw`r^*S$7WyK4|0Hfb6(YuT*>_aI-8 z#PctWpST4v{Lh<_2E6I;pJ?1xwEHej936VvAq2H+*D9BC!pxtDU!8rt_SD{X>;qyA zXTp$)A^7@SHF~Ocg9tI(VhGYmSPdlD^5{GbMW-xWcT6HFf|71MqrU425r_+Kh9P1| zzkG$u6Xr$y{ndn}UYQ)DxT!%X_l@xg6gDRO&tvvTQN{<%&f34g zoXYiZ%c34ciWV?GCh*l|Z>lIHGVr}%FAejtvrE}+Hr@OV5N<4yt{8qje4mb? zo&>W?vAOdWPy9VspBR)vHVp{@jnWf=OuVnKp?CGpZwWrkBY7wqN`niKTP&7f;iN)FbfXWx#_-+nfl;z2qKnXOe>N;|?FO0ohpzwiFOWXQLP0TSDuZTDY88)~{m7XIPw zQq&nf-<`;Dwlh<#ExRZ81kN7p!c2;&6-bncEa$k9%oDeVV1ajWYdG~}mBXj%>|}s` zcxTb1{33~kEa!n-(t=w+lNehrjPsmm^p3jQQ!>zTrHK3=Vg=%FWHqo%tRCGzg*xH= z<_pWv)-s@LU4e!4l>J;zknNlTvJHM287{A~!CB;E8dad*eMd4mSZOnxI@89RXGLHb za>$q0hJpQcZh@RM5fOOfzxFvk{tSfyG(N1EUjblF$oWQ+_7?59$@vgvUq;I?SOjYw z!{t=2sO9C#L2ow#$bFs;ePlM%e%ND0{0)Boo5lNZn89OIhl{_fg>cm@fD&E(OMoAXH8eZMq1sN=y5byavZGG~tK{nKdT8~|5oP!~ zmw7Ne8Slf&JDv5vxzBUv%&rJAHJK>{K|4u#E>x{yP8|Ibmw0~~6dC6W`bznpCfU^D z3GQO!lH4+lYSad{f!}+3uRWW)Sf?DPWTX^uc>+mX%=mxd7EkVt6;NjwoC!gGqGHp9 zOa`D;!pbuI?P*mtaeVG(lm0C-1T^OFPxqpK&1v%5S;=5KC-Z!Ynb}^L_hf#uaeA*R z)}Z-D49OKlBBIv&CUe}{fAHc_q*#3qtqwY6l4Z61`xmW4$|{f!uf6SF9)lvcS`TF^ zhtXb$euh0G{)`a$uOZsBG=Ctc0Tp_OqtY}8t?JE3KO}xM(LaIw15VcFFErXr*r%Y% zCO58%FAnh^n-6FUv-%6Im>goZlxEqeeP6U&G!pCckhM0^m>-;3uJAc4GUPSMCr%G3 z&lQEBFbuSZNV09S=eWpGtbcm84VeB~73(H{wi7Yiio@}oJrmI>QKVlYpC!ucc1ShK zSJH9|r@RZ1`@jFzxBDE?m5@fKCxf_$Y>ayzKOC$Iyn02YZqEBgMhV{a?boc2<5erV z&h}XGQ&{bgGFTYHl!Ql)p7(E3>X3DWBKURE)if`37asp8WlS+&t#2jUNEIfA9P*eh zKJK%v1k+pMcI&w4C7d5k=`Gk`CyGDR-YEz_Nbk-p)|a^N{+_?se$j-Z@9*!KXTjop z_;>jm#8gKhh<;jyf5>Dv>1eCFx9Q}gAJ@l3yulFudV}G93Ld;d8D|o6&;7)?u=9*i zJxmtBV7nhlrfW!2*y+dpsY_~onP7D!Y~kPA$LF^SR#!2(x z1aGCzmVi+9oGc>rVNMEb7{uPyC$z=o)9 zN8ukgj{DF>_c;qX8MOC@vrFo7vNHc(V97R)DDv6^Juu;t1mz_(?kj{3 zvjD;5?G)|nqrz9s#D1ulS~)z|CZ4Q*SAAZ>LrHZOvphubOGw6NC@C~vo$fkB>0d_> z8P(!(-yQDvU*|AzSm4AXL)mojx7*R7h6mhiW&dU5`SlhB#0v-uzcy{iU_o4P(n7(p z7ARej{HOYMnbHQrH@Q1IW>ckg8rlNm!h%Fo<3*O3&|V|9b&UecJ7;&NXNBCYy|@@S zZks*E!Xk8~sTgQt!^?yyWv}9qVB4|R+fCFuiEdQCbF&WrgC*z_zw=9hF`IxLLhs^` zE|Z?Q>RjBod?M8GXXLv{GFBi?KV`jNt27}i;@^yMng$dn@xYu^EGvh;qgb5}A#I<-Vz3-%>$PqOju1{XFwCRLUUffDkKu4M8Z8})*lP)g(;L9KF1Kv2fx z-X%8sQO4?EqW6|MLjG7ux+l60FVjWE6VpN+o6YTq$zN=v5%>Z;giiEJF?~9f#aYNf z`S+Vq^Nj%Qz%T~NQ)+C#d2xyI&A<^S=n6I?6p*c?&lDx%x?|hpUBvmGDpRW z;m?PcoUPj3enQyauEXto5e@>+-Nq#KZsxFej49L3`A2P&OYLT=gc+mtxX{o!jj(&b zh1MuO6WDMxv3k0)SjyGaJ{nMMG&B8aJ`Z_Y*4{fmt7RCSh&)iz^(grcG-y-XUKLu zy&B2am;%>KAH|CsgJMLR(@8sb21Y~1{I9l}F!-#7JWGm>eD-&xime!K?;+kz2x6;% zwHxpOJ?E9vDvhmT&OU%U8o6_d|DUAG=Vv&9=d3$aM}#;ONvSv?jTiF2 z_#_kDanPEa)|VpwaD6gsMP^BaEOW<8$nh<%m@2QdeHaSvY~23RYJfzMh3UVLTv*0x z&yK-Mq#i-pLbzw{?uzHNf;xoOWktrXqLvNnq-inIcIEV-F@HDxYr#(Dnfh!Z%2`uvU z`?y<=!GsCm;RJ%1ep{91YI#Zf_g_P+FYClxtGBf2T$5uOH9{F(d_`6i4* zoTI>Bb~2BrX1HMbM-V)o9F;=>&y5y3-h^YGS|?=16hjV?0rJN6d-D?I3yxy~7n^J> zUd4}r3juh~sK0vhj_K2&C1fb~=U-}2U#7HBv_5@Wc-`9+B8Uf;>7oqGf4YY}K?kr| z!nD&Onj`t`i#=P~coRIQYipM}2+B+r5H7X5YHnaxDpHmfGA|JDM7w&Tcn70tRg%;9 zW}Gu^7i{h4y-gbBO8a8M5Pcwc#(#&gcyEO6wInD}s}?a1MdN1O4Zpe{-H;DTd$)e> zPHZC@;Da%9mSIJ#+MWAqg3HmIb=APk@fWQK^;8w|r=fM5;KNo1C?n+@JmKYMDSxsT z>Ko^_zx!=^H_+4}v#j6oc}Ac5E<~R6>1QWQM;~+4Hts_<0Jx9SJCWMQ*p_<*}I_H?rcr2$~nTd+T&wYZZAO`1P-rLgZo&Qe*gF zK5m{m)8!9T`p*vGK}oBJJaygz_@Dgui7C_}oL$%PrmGPvNt;m*d=U5t4VxFyF1r_Q z1mH~#OujF0?qryqY(M6Eh!UtUqPf@3$+Gte#+|bW2tc@6SxW2eMRNllf<}SN1D@Nt z7z~BPYYA+PQQUaa1Oy2x%pGVR-6pJ`$F6N_l5cqo6Ja^hh|#ktA!4M%1aaNrxZ@6z zSE<{GiO8L+Dgq*Db1D^i$mUAF`%<=t{ ztz~L~;?h8l{zOlgeX%kTLdDPWGwuFV2pP(K^UQ{du4|d_#4 z^^e`Vwf{1Z*fU9w?A8Prv>~zg2V1o`(pap{2;U-)h;y{<2(X(v@J+Gopv49cNDSS= zybd>2sKuZuh)AJQ2o|8?2*8L>d+Wev< zvv6C(4w>-p@;zf1%j8E@%LI@o5-C7{xnskBOXmx-JVLm^&frQ*zb2CDoHfJ^x}5Lf zBl22Qo{2KpzQW2i$fZ+G+=pn0TQ|iB+}{YGYU0j=AgWjt%{1Zs5%QD~=|$h}(g9W& zJ_F_t!pZ-|pt-b7Lo~0_lFMJjkJV#wPn*buGjdL6_M{AS+9D%L7W9+lcZh9_aFLC8iO#G5tH($Ri?!W z9#_Ot>(w4ZTjH`$eWfoM>-H9X_;o6!-{3a+jQCSTZU*-%%?1Wh3d9WpugpIPUW#o` zHu$sX4XR%B zXN0v}x)hPhc^9+G^NYkjZ?riq?@OUp)02C{wjzV=iiF!kX@k7Jsfp&h+8c@2&2Ok_ zs=;&c+rItCA#Rr%llwUyNOdoCawN{TIu??^A6tz}jKys-ozLmk#ZoI#DeyNNrc2mO z$XgsCC>$g?@5jpN8g#v8YHRBOYPJ*COvHxfr7YWNjVymx18GS$VqR%cB7mfLSvs&vsNZ} z>vU3%@mM3^n3h922^q1;gWVDG*x>GmWvJ0LOi;?&B|&$gy|&+xk#9x1R9y5?1lBzS zfu;bnES;H+8`IH6QYR-r#6bU?5pO_-mDbc;1#ZJ8r}2x#l5qD;)MS(;)a}Qc3Fggz z)&jz0a*THEsu<#UkNmJC>U(8YO7SqzE(ILy=MyX{n>c4=%1kC5_uOW-xC1tR4{9)* zW>~{UKHtkdxM6C4iSgr*1&Rk6RRk$b zm=E{4W`_{ZpUst`WAM%vdmC+suu4y1Jax#E^+6#Rqgu<+Pl>wu-uVBg;2~F<7~}Q8 zEbiVQU@q-THUxL2H)smi1b-FgH$B|(+mU3G?&y$Hxa?%=RA}9gY-X24rvXg3{ilq& z1Mz!0XaC3VEd*~;f*Sva`j_~r}@&JG-so4_ee^pG|a32G#!H&_P>HN_a#W$ z$@7OF{E{t3JW6f0eZPkwG2nHSvXYGizGY9|Cv;@ykvBT(hwhgpkY3$FR8u-;%W|i$ zJcXtl+Xrr<;{-Q2lDEd;bY0flVWRs_vzEBI>~{XzP7@h_HR=ZoTfH( zxM_x+V04@Fup`==L21w~z7&E`27N;^&p(>DL!HfF@?q91+q9V2oxptMXEjMVkSQE@ zr7C4A5g5ZO(b0I{_Ue=Hy)*U6K)1ftZ^m%Xi4;zTeV3{qfg|TdUbY*aYW;(TuCRNg zscqs%nzDbuKPYNY?=wico`cO|j3SgVY2ih5YktdB4D`cu&Aw>9CQ{Vt2pgHRG>Nc) z)Xj##f0of|Mzk%L#~XWvRhwG(HBpSE^@5Qa4vWF{%6956;q?lvHZZ6U5Rb52Wy*TM za!^d>)#qHuB@MLDXB#5~UhTi`1^E`ktdMP*8$!y&V^KP;7jl8W=y+F|K=eCZP7T9m zRSw4NDmkB)*ZP#As8L1;i>s@*BZC^QwJh0#?-=IR_?|CaetruwtO?*w!KSP#;z@mD z67~8^Xf~5QbwcxWYx9(0Y4$V4Ys=?LCzrBG)UL=QD_KiNJCd;?5rfHhjAoi!v)iDg z=uFpX>Mxa)dFJ;{#zk}XeYrMbX9ClBH&Z$C2OZyqW_Xi|19u4*KrM`hk-zN3zMdQ0}*?d|68Rp zk2MEFQHO6)(#SMBL)rhNXJ@r>EUnUKmlSn+-m;)7xH_wg)@;6I%{tgavt>vOqsUMn zXUTPeQHB~k2-BnH;~W1Zf17SMcU?dTf=Hp@=fr8x{q!Mr=`%`9e4?Nha(*>fDgz~n zUKt?__rsNOe8rIHiGE8+%h>s;Xl+F;agozwV$`&!s&sV1{q2{u;s`rhiv}NU^8K#q z%7X#5endU*12$pOBvX*|uPhQs)ArQxf(5w~5k&+DIFTpnzX_pXv?sojJ}%$lYmUTX zV+b0@Vh@&&EO)9hHUF4W=dJdV#KG}tSvc;;`Ke4rP-M|aU&RP@vCVi4CiutEP#4Ll zS5-tK+$Z8^9FcDvO?J9d()K&OHLuS6=dNHzj@$X)PCegQ&Q8haY|4rAW5k{J3;1N`6~uqS54!A-lWDg>#(<-W=#?$!8DmWT5_FEe;TW+j_1BAYgW1G4GRWr z;#mXNX3Zb%>`D0Zw7)5WKGmdCRF%}G*IUmTs?{Cb>UK@XA5`iZ!SH|opsgAykV48n ziD`)hk)(laZ&)yBAMG{RQmxPQ)(7YF(^n3C>rXyVT{*h$y#ozHODs?^r^#4(IExrO`%4^DDjw&#thh_ zV-*(5((+uVZ#@+nQ7mU0(|M7wV-nqffrvlwWtQ1=IA*eC;QYpG75zuZe8NRn=&FGG zQM#;IoSY4U^($^x6V6Vayz_g^R)@+xbU)a2f$N8$ev{5P>^L(Q2DQPczLJs6)A>4xo0qBj0$bn)rN42591TgIV-}bo=7W&HctN^FLFbo zA-$Y8Jm$>9n39~A#UFzLA^Hw3ey+>VGNTUirW}3QV|tAfzI^TIqFtQ=GK(0j_xOUY zIn?LD+Vy>W>NdFDHhMGJE&PE3xk{!TZn6I|M6_WB%6QJfVcS8YquELQgY@>AO{(-K z2M}dWPRwwo2ynKw3$IA%hkXO(tUu77#U;Y*O`-fjidM6TH7;bpkj|sRf!c1 z(N8=*`c*OUJ#ViJ2dA+KLX5tE`245;h3I9iZ0e4aLo(lB;Yk`5cGML~m>sh0*&Kbx zdAJJUss+OU1_kXFRf}WLUH81YPwQ^k#8Sj1h9dnfbw}aIXow_v@Z$iuR6FJ&dzUFy z0L{Zs&m$i?Z6^i+dHLX&kaoJH>EgXM?!9jfP{Q7g*oGC@3YSbPP7DmXFK@5QKkZBo zgX_gER!7JN*!z(drNR}q{dLxa{KgoZM{bXs^J=!m#NaVkl#^U)m)}~?N;g2Oa~X!( zV9N}lb+pxX6&`rQ-c+&E(cN(y?-0T@!#!#JY8F=#>Ua#@AG$p)Ua*beap)5H@?hI# z>@M`XY*{cD`fEae#H|@7&Kg_P)nyIJtW&&mvqD<>Uvl>B#S@DaL!jOQbZ!_H$@bNv zzwR;|`@PwpAcI2i`s}QDVRS6*@vL*^!cG|>jb^%bBrM$7qqmWTynfyu!-#)TBN#BK zt1yjkr42EnsJ~Q^aNhcF^$cl_z23H@#?7_X-kf32RiIQa;fXR*hd*CKs*)5Wc(H9l zs&QBhjyI*2vZb4DKQ2!$ti3a)?S&U&ZG=1B`(0-Et@^CFQ9s6&@9u7OPOlt@p+GYJ zNfNnTZP$ZjHJL4IMoRS+tHBj*@qiB-38>!u(_O^a`^90c$VcC{NoLKhuWe*W2~`be zDg~O`QJaNYK%`<^f2GW5W?y@1);uVlMP1Z@SICvz8Ws^efH?=XGk@2Ftf zw$j)fbs6%Sz5j>w2(FCKY5~*jw%E!v@LqQ3w5p`ZvfkB{U0g8P>%kZ(_-8sZe)IK7 zK*E=4erd9Nd@lq{xH@VpTH~$PbX=&NRP40fx%gGVZi|HJ>Kkk?u_83uEd`mo!1a7D zNn|{9exo|$ZOVPpIp;0Y9S$X|m|4VYUYi7EY+xQa65PmrgDnwh60KdPMzAo`mxuz( zF*TOoP~SU&Vj4G9!uKcKuBMOr2!;z>p6Kt)^aWaLZQ&7#!i`Sc&f@OhK%n$u^HgtD z3cXCXrAY;5wZa5DPUX!zpWw=UVSyxd<+)_7;#1adZEM^1RGf{>#+zubVUuei0;j(o z&c<`*WLb3-^?aXHVEM2o=1;(w;}JK%|1SB?rO+1}J-TU`Re3w{`kl{))rri&kbP{Q zxlqHfOopvOKDk&EKY|2yZ}2v&x5T_tA6r`e_JNy~c|1@cGy@KrnqR{D*aQ~GUe_s% zshHL4SHFY&&_yIK3-0EAsU)}}GU-m~cWEBMg)r1LgCPYS<)sxHc9o1c7EuB2AMdUc zdJ0Md&g-o_)*IbS7#(H8gz%WkX*OT*EYgu!;u{M%)j~74pOyY}f(E}m;2(Us&?2ym zQa9HrS*qVM@cuPAIa;Fmp4?~^KsX(@A~%HKfQJ_u4QKiXva&HN;ANT5>&><&_|gw> zE0#RR<8S$PU?w(I_7aq0u}Y|KRGQ;BzKS|#D)t$yODCclzv3emsM( zlg0IU09Laysy6*Cnqe(t{*5jPm956$R|~5iC&NMFvXHK5%*40C$`KW$;y1filZxKN zzieZ@PD!1c$}A6@-{=c|;>Rxa&pw=t?3=b_ED0OCC9o|VZq^UKeG3U3RpR;Jx&5xr zM)OPbp&s;M9iGSHO%c+h(! zB0nB1!BL9C&N_!ByA|||HGVA2w8X5?T|ud}R9DjPu@ghZ(!-Q0&UTJ~!gf>60Co-{ ziTXj7jKQ4jL`UZ{uGf|ugbcK0s7;Q@q84-?ygBQgG!f?=2yN3QPPa)$bXgI?uGje9zH5n}`dnmKxV}Ju?-o_*RR$XKy!f5_ryL7{8$kIi` z`qQ_-2I@Y|g9Db!HwUL2In-Qwwk1NsePfbyf5%%<_SSN8+m z#IK^P4L=4hH6mKFOBv>A5$@UjfXA76&yZ>12kX>EKZ$zq-Cqn`Zhhf;+`IefV2VZ! z-%DCz*1~?rQ2UorcA@v?%ZEF1y_9iFBGd+MM0nyelCkuxOYQi57*vF0g`F#1z;my1 z!xa!hL4V>+lQh>mXHalcyWS*x8k@b=p%Fhr_Q!2;qvw@2Tlga^N+JHd#bC9vt9+Iy zbU#C%Jskg@*ecuryg$x*;&VIO9(oR6=;OyhEk4obI9s!Yds zW_|Ijo(fe0M_1s8S^Y0}Mj(L%8rxw}@WX5AiD)jI&#YU!@jS83-(<>q@wZ#rlE~9mt`Ov$8gLM7JP&5^(H&rkcM- zPV?#IWK=4xOLadWaw(K^4_3E%jIHP9iMbc!6<$NhvE$F>Ht8Xt&GSvmt3&&#U!Jyk zk`T;u;3=50Re$WAm*`TW`7E=hT*7MZo~Wzr(v-9EHGFeqOPU^<1nMRymb5I5DN*y5G9{IAiQc$M7po)O$DwX(VKbbhAz+I^)Pu~fc~{AJPEzp+Nx;my2x zH%hBLS{Vbc-3zM;H{G?f>a&0ee;^3M9C`S#=WR7Qu|$p?{?BChqE-?w%p+>G;3iup zP^{SQ#x{KVfFE8K>c-<#8O`t;W!k%|9wTv~2d&2UOsfBE=~6Vd?D!Gq_+{Rwhnk;z z=3&YTMa*NVZohUl_}wz zn(-5G97OL4wpc_m&y1O36`-Ri#X$dTx*tf(Zh=85%;aaU;D=Pd;pQqJ>Aa@(=z8Pf zkRwp=An9?lbs&u#)8*&kYR(IE*GNq}c&s*%vO-dKXwrzg(N)gaGGprttmk)xluTG} z4mu6gXQsr@+zg<|E)Xxt}ZaBU;ffsFzR427wRuO*~=+r=L%PDC9sGc2U5; z>Qx7P+>tf8u>$STn=eoE> zL!^$FpFfpygx2m793XZM_cxv04Sox}>?r!-d3}C-WvfH;U~DRUA%ys8G-a%zh^ls& z&J75cj{G0hg_iGz(-HguKtEtl-Go+iz~)Ji#Bm3SFJDVTN% z45vBdGmeT7<`yaelM)UShyIxIsM@|{{6jxLBox5P2$LNUigb`eZdIctl$dYyh2YLhc26zn zD(mZ(%=CE=7DJ;IYAr>^rJ?B}&Ks3Gq&Xz|X-+4O+(5yb^|ZoBS2_5NmjF)3)0b{#AJ$4sZsE1acXydzVQ-BY?NyoARsz5`3+VC2H* z3_i%(PBcZjEL`qV6rtn+V|BMeja3xxGd}uNx*xZ}xF6VXp?HAP4VjjF~kD|JD~5+dS%?#$?B zV?uZ9lIcfk?0U0QpWOKV2j!S}@D;G%)ACm@zjF zvF0IG40N@$oZ3g^#elyyswg7i80=q3vpBZ6>vPc=;L=~%2*S<$)C@x|rWfs$HtZrv zf-743<6cpRtP7?;voDSeJkN6_fBo0a5I$>;GxRJ{hgAiJ!_4yYtA!(&U)1^csrYxS zS5wMRJ#Vw~KA$*|4cMPg6_HJ}U*Jtg%q5s#!~t zGcEU;rhgqBWhZoN6qEXjDtH*)D-Hh(f=GMPja}juc{d>UW{f1KXnz^)J1m$IwWQ4Y zQ8PDOm(vLv!HwXGhqS1u1QjG&JE3SfqZG!9I<*Q3&dMptspXSv!Y4_=^eYb0M8_{Y zNkyws!n{X|di>>Rp2#X7;m&)`jvUs6;;97R`j4dD?V9+^^Z|WdbkJRYi?Tjj!1eCt z1$TYxL7yIsz_NO}0Ilv=A}iif46(fs?Jtu9cHcgO`htn7U@{S-fJ% zb78RgNE+Pcy8#5aSR+OaDdG~mpE1(1Ui#EC;*;ZSV-7zJ$|~~gX%5$Ku^!7_v4Ugw zd&wkvJTCAZ`nsrpW->B#L{G>j+2falVjGRH*LqNDqvH6A-`QTSYi4>ZmZ^hHv9vIY z#nxC<#jc0!)NS~PEycTVDD&G}tiR;iMRUGHb`n%IbiPpq2 z%XVqo)aVn;+17{4XB}(Ii<{w;t69w|ox}*qnJ77llpM557!jp{^|ctXoZK#ji2u%G zbSC*khVLm6JrYcD zn~(qT-8U?g9$Ag%RZo(*elei58{^PfbAu)C!<-vPGpdhbf1T!L6o_%QdIomHiaZB8Kb{~ zo$F#=lV7qEq5hS0K`@FPGw~!W`2}IZ)@$pojPv@&u#sI7w^m57juVscazzt#?wxSwO3dRo?4NcsVpDa}pCMK#wCxo`5y~&*ezMqK;1S71E>xq5 zqfQTT+5@>V1hCKQ&}DfHF3Y~!n+DaO_k5@@HJ0~)wmT-XlLSKdF@3D`2iFnv`x(yKuW-A%x7Q-?n$G(& z*FPg<6CV;k4kfJrg`g}fHN_wcKT|#0K+8{A1-$0SVg)!9<~zUep@yHuD}=N!3!tds z{ASQ~OIVk9duYFqCAB?Dd#b`uV`FK@_F*CVQC!RyECzK6OJ}Axx26g%n7x9JNwPrGAw0!`n@c}JaP-&$6i9EIWL`91oqDi*&P(hLvFzf(GmN98TcmvJXXWiT#CIhDR} z5~bbRe6Fem{_m>V081AjQAB&1HD5qrMszdR9kEc zZ$q#4+~pb7hBdEO_dK(?G#E#rj~Rc0?d%zB=%FW{di)#y6CVz8jpQ4E^F4XE!eD|SZmi0f2{ zx2ZMJY%_%uKyJx*=W7lR_pH1~(9xK@w_d;Gi#M*m5>KK@#S7EJluOEQe=sgP8!O^J zsJYVJ{to~zK+wOAV2>THh-qeXojPcVxNt0{)lmX2A>4>P)ZU7D>yKFx77;YHnEXX^$Sxlf=jauaDY7Ak6A_3 z_7pb(4*OH-k}w|B^aikSZ4TWg$V{d$j)dM+S?$nBa?P;{CuJ;2Nt%|4`Uf>; z?MvJ%);Z>SwpTz{BPbdlPJxB)%eWdzLMMU}(fvo+K}+?W4Fh? zP3=};n#Zf4tadX+u}lALK_Mq(HXgcKfoHq{Xv+eBP;yT^Q{WCPLtK*m223c6^aRN1 zIB2d^w5jPaB*knTVHiYaVx0pq0A&Lnh)kH8b#pd=&AyOm@QH6QtDwuAjMOtuG@aNL zqUNq^d`zc`P~sr>gxT=dk{C|=h0^DYp}dNq7Zb;n%L$we?o6{sl~-AG=usJrQC&Io zJcNS4_%At8j((#Xh9PLC#Z1|Q(01kvY0rGd#zppSx_$KnEhikF>0NXgJB~ffc}(jR z^K`O8&TEvVCqkR_XPNVGapj#utP-fVsl!x5-wJml>2AU68w`fp{Yz+) zsWg$L*cjPFtxZ4-^qPHP;ewqwA!yS`7{L!0PGLcio^K^FLd1*5B~6w6dKzP-tHD4p$gUXm(4_OJZtI^3R|yRg8Wen#?DZ5@lFKS#$z;C5rcG^DH;;eV@V;E z^FfUgpla0za9zufUruuwc`{#oexh%b78Q4%5OhM|TJ#@gm7d`+@TSm)OHO?JslKo7-k-^Rpfs5QZ+#-w#SF95=2M&`!`2c)0yEIRzN*nLb2R zl8ZptS77VL{rkw~Zbk2ZsZQGBOc7gIU(0B$nCg==o1ZThj>@{vt0K*6i>s3nN>2Y# zWom*!C$!kb*{1Y}2r$VX<0blyAwSWt)_Ds5&QE8{sPeX-xCynmFg=1|PDD0GK#KE5 zZdt(!?Xp5He@}V8qr1HB4})L07Y3v1a%AdE;*~Q13MB3+7f2aB7*EWw=8u#`U>Z<; z4&%@TF{u=!3B51Q?Q93XF^R%cVo&Foq{wBMqtl$i=;zHrX7Lc$o=MS9z|Li078EO< zr%&&He3O5tS?>V6c6!3#i9*vbjR=+oZM(r%kzo>{;UFmR-apmD8cJeea1wtV|EVi?idcu`ecb(z|-|K?+nR1YaV_=VW@g_{?+ z-aE7ZeY1lm8B!K$6ocuMt=xx3jHJ-wn@-Zw=v>|H6!oD0Rs`+$Gg8bF9%*~)iUY=G zr_S>yQ%qo!?0LhbJFCrJjjvnlPEy?<8D}QM$yjTj-2z(nYTSOXH$PlrtEgoD`%-M` zRZ`&{T*EqsDy=JQ&@u@!R8yU@Atv|t=~E}Eg{bQ34eO<}1|3t#1JBre z=he0lD{H8vK=E*jjZ-PzFW6Ok<*f#_c!JMD;yreJ+=@#j^vL0`LKiA^MJoC-50c2omYAwO`#pHFT%`ut_;AsUwEl2ikug?UxfAeZ$nIaCv! z+#*9W<`g9C)8Nt5WppBGZGsgdi`BAiu}@=Ud{mD)v&l(;{bR5@6JJ=kc@8Sik-WE5 zRBU?4cp(1JOH_}?V=tRGldg=S`MdPS4P*&(kqqBeXVOyD2Tj+Wi&U(5Rv2!>4E5w0 z(4WO;5{|M;esd&GaP?bAU37|u+6x)8t>r1%H^ zYE>d=n$`2+bx(Z7+O8pYHS2KD_Kj7E12gF7QYzXhj8!{|mr8GqDvazkaYq&zVXeiW ztxKO@%8~0hJ%B@@YE~3Eu7^l7ohYK7ut|7!{EbJ?c*PZ?$%%8DXHM7O0ahFuA2)`? zK-mwe(*9LRDGim+5QrT!OcDE$ojifGzg8)^wdMk5RaeQ!!ylU}w=N@I&s5GCL&HSg z;3wOKWL7no0?SZ80-Xt))gEkA)O!JD-9zuGn$pl-wMch4a8^JUrT`%7{l+HG8Z56& zSMeysiPAVl=MD@!P0ETGdR9$1(}efni|{`J9T13ve?Lvo!Lr1a{5LbgLFZU*8CHIn z6(S2r&OVDb5H?LopM<_%8|wS;PEMT%a)X{?6IQFSc&uUSTG{5(;Ol+YF~P2gy%n!K zWnw>#lOZce!B(_R+mPjPM9P?su+$cp>*tOvm4!}R3viSv?SXQ+t0%B*H*$xy| ze`4Y;ybz3+W%xoH>tsGG;7OKo?pC({cTbvuJg`{95k$F-LR2!G?kxc2mHQ?$Yw7x% zmRGBX%bu?~`zVt=f%`5zq&{h!!SF4m3Rc6f?+`n7b62t1>KOUVI-FT<&dDK@f+L5T zNyBxPj-WJPjt6pswpavo*+|VUy)InmrMMf1Er+^BIl-(<52v9Tj@|i!d{`Ll;1#rp zV8`Vc@hb*7n_$<5i;~0r>IL%BT>y9Fc33Du(8#ZPO(jh*c@G;0v#gIl9F%+DqZg6r zPB49-4Om?@sPWds8x2USS0aHN4XTT^5oGdBce_Mc`CPD3X;^)ha+PKp{M%X@aboqE zC&(lwjTy^Ln}PdTV%1xl@>q_3%seLqgHMo3LHm%s5Rt4Ntcy_+y@G2 zs)xtbSa`U@J3Yj9Z(^&N{NxR|X z>{-kJti*VgURHixp1HV)xV1PIR&x|}IJOfjK@$N1aasaaSMcC&6JGy?Hn})=$8uYA z@-cg8M8E>-6IYkTF1tJ6yX#!jR)qnuTnCzgi!qNm@cF z$zlaedI@4MR%AX^+m->R)H(X&Zui10`EF{N zR455aTUtmYkU^>)#}w1_Gk11&je>I^RX!1nwAq$(-0Pf|URqD5&mKX15HfgVa=DOT zbk|+=8_=bP3p5g4J~(Y#jarjar&nnpz>uj|2rrd1=jGmam(i6$G_1y+5ftoy}cX#MV&5|6~qS zqFbjWKS$G$?ks$I{*T$IW2d5LOTDe@nv!;9$s}V2#9RgS5h^h1(4X@ERWMd{UB6b0 z1`>VD?A+<%X>YU>m|PU009|r@#m;o^{H`6X$7**|F=xkPN8m_A!jP(Z*IXFRPz@?P zFopL^K4{!dzHmBX5VJHtP@T(OLQj$Aw4|Kv^QcJkM8Ug>&bv5*9wVm&)2j=?cA zZwegUa9mWR8V>UDxAg_lEXR-`Ahx zv2G}EEhgaYPF(^M2Ju(GC@Bra?)59JN;#Od00#W8C_JrBX&4oJYF#8?<{h0}wENqd z0ewedf`2od27bZ`$izh{rP;|cIbALgFj@7bVx1D?yX-D%y&Z}2CEnJ^*j-KsjND0JvV3|EgmB5%m#!h0 zJ_zr|T@3SOgL8WrJzaWIM^|Iz1(y^m!rUzzGuLsegY%~u{lMqAfV|{UI$eO45Z{yS z;{?Vy%)szvr8d0Hj%_k6U1}u;*Y4&>RV+ zCUZ>3XcUC!d}n%2ojAbd7S-@v}{%ajal1s0F>TV8xB zGnKw2M${8A`Qs2FbCxA9zxFQ^o@}SgF?ex$^xyEqvs=Tj;^2@8q1RL~R3^hU6%j$cJ&EBa=p>b?HbEPciN7Y)6dO_Tc4EPVLiCX=Q`b6<=RW$RRhVP=NNCU0T4`HJ156OMt24BI*II zI!5$TM_<%BU(r+oZz)p3mrf-dn3$S#P$G=@PbbBX2_@{zP+#6WTLMk)Lrw5xD<2?e zy=93?pS(0~71z6UV2_lJzhDGcGldXK@&VKj7og77LTk_}8Qx7~O?da?6(P++pnD8jI{im?OOIL|KhQYsumNesC@ zLS6TNIoA+g17OBY6a$sd2630$J@uP2g9?nNK@0~np}}N5`>QU{X<-J8YL{w2m@2w)R-vZu4H#uDL-*}_E&Yl95>mP5 zMPU)ciI>aL-~ELe)Yw4D+(o~cEi@~Fd#h0t|52K?dtoW@XC!6rd!8=d^*_HjMyp*0 z=;oo<`%&W-W~j6g_+dY?8mzhf zW4*Zur4>HOF`LLYwF)9KD(!cy0d_-V!eM?}tO;%00Pw+nZOv*3Owta z^T*(+h+&CDkh~T&3gzm$-K&@uxjiB=VxL@B3Gl$3Or6Z`OktlSr}KY|sUpZbIvbie zPPU{(|2isC#}f0#4c>1g`(eTnDqH`{8uPM2dSTwn z5a_({Hn*^5i(eiUgMp%I(N9DmzxIZJADASr(n~Y6!3bL%yW>Au0(Lh46L|jL81+t&+A!44KPo+jyiP?-P z{sf8|r}ZtMBV1i)gd-x)T^K$Qbz-q1AcQw(1MJ6hae?0OXg6F(WC8|q9mHouk+_%& zUt+Yb*EH!p_4{-h66TNw>i)vTKPF%w!0nG=*-si}nuBmwluc z=3O|Z%NbY$AJtv2KGLWcFDpcq~)C+Rb>xs*mSC+{QLc{N!DmR)}!g;}74Na2!CS0Lgky6j6{7eQzRb zL997|5HhvSFN$Y~9c7#Wm>-VIC~NXR(BXg2mQ0YML9vojH?t6z3`1ql$ZB`tq?> zxMu@0XG#{Fpt}zp6uqfMz&qAxdv$9{RK1O zGFpfj>~;S!dgu&ZcxNZ(k^E*)A1J#c%rMrtOf)zkDdle4CQBrk5p$UM`e!}|kz(AQ znW(%&X^sU+BUc0(I%XRXO&vh{H|U)CWoL~u8&PBqMJZDXs~r*6^O~PcB}QE zT|r(aUT8aD*On+mL0eNNWvU@2nZ-d%2s4*YDJ&yAY>YS!+GtCXCf5h2w}bF-S%zQ> zES!Dp`^n65lZ@@r6R7aqgJ`5@c`nakEgENQ`_yD?D~KvK#C zH5LRU)L`pkXoZZu0(`|$p>(Aug=!`Zg6FXNOVYYUPKpsKR3J&=I6@WmU69 z;%X?hufEumW|Jxwe`8sj|3p9vFwaOWMAf%w2>qKRz(eTT zISIFy9cqJkWcx%>Y9yRp_bY~U`#%;CdiYK+ILXBFu6y`rYHF`VCkW4mMO==)@@c@! z%lLDdKAi9a>eH110BoeNo}7~S&&}Tr^VBvoJx1*rpluZ7^O^=Ix7nJ&_P<~xP&}|k%Us=_k zS3d%pK`0<#Ap42vNhl2t_>{QI{y2a-_H9C&@g9iH&F70ly;3LQbCDeT;|q^gsuvER z0w;kRsclD=WGkR{XW+apM!X)ore@3~569Mwak`GSV!d z-=%FqWKd%}InPNN7{=o7c5Wj35_sNwN&agofs+5r!=kb1tIg+ooU;FC^ZKmw?QTg6 zW2G)nBPYIyw7D1(pk89jB>?!`y6#q1I0LkQqi$t?pBG+3ORYqiGOS_|yRj+s-yD?! z^z6=hT*3Qa)^2Y@`?#IW6(;%l5Y5}cZ^?|i<|1^vf3D?>Ss$PiX@ynRsO?`8;q^` zq;CLKsKCI$RwNXxK+NG%rWt!SAv7;Q3Bf_iPH(Ogd#D`^fx@U)S-F!U z=jwq2y?l#>zAN#os5yn7XkR8G1} zA#p1!mhW*dX=Njpf5dU6#neXI@7cXZg+6aEF#JwJ-*Hh%78oF&hO$hA(7#Dyf{aTZ z&KV@6PT|we$Sn+h@o`m%+y)XVu_NIem5}dmt+*Gl1KNdtiPjnUgMs0c`*B*p#qi*U zBF-(k16bx50R!A7s;y=8WBxIoqJk&Mk#TNWfl<#?05+#FciZqy|Ac(S@Dea5y4DdI zD|CHi19AIF;imrDa-OW~)dd*MUJb06fdT*UHN7Y1YAqZB3vzl>5W!UM!h2(G{v`vd zHj;yqwL_sH{Y+=+k>xw%=W?>KG#>rsVj-XllTN1&4hyV8jPr#*e*`i&9Q!7ezH-EJ zF`W0+)tmYLsp$)sh1aV&Gyntp#)cWe8lG4@FLLFtNOa}j*(Mj7efhF4TzE|hQ^1c> z^?P*cOhTK@t#e4AWWk@c^)}C)`5OX3+D*ihvgGQ?xQ4ghKbEk>6mwA9u`G{iYFr<6 zjiV6YEWD!_$!vI3;Xc_oIx##-33GdCA}4Odxc?Oo5F`V{j84W5Yduf)kV0X*;<_zi z&~v5KAa?Q-ybi{JZ;Dalcx_*>?%Qo=E0>eig6_yie{WQy1RdS%Gt=Yo(f(dMF{J1^a#&IU-=1#|>Kq(#E3 zAkw;#`6F=_k%yc#wolf^lW#R?ckG?bbu`uZex0N3Q;Ui}4 zVI(vvt8`Q0Fg}dHypN#Xzo%4Qe`|{XHvg}c3>}8}XAsIe%yg$(Gpd36c(`Hd6zpp!H%aW0^TZ1H|{e~v8# zbB%?PKpm$=hIKvKy11^K9&mUUYT=Gbq|IqNrX zBP6_G5IWZ;gk!eu^kWp@d8E?AOLc!(d@8v$?*59%;9fkaV(GhsjMXKk#6T!H^)hig zUUjhTUrH@pfe$p;XWPnA+iF>DM>(td@=weU1=*07sCCxzWg)@cuhT2G0!I(7-h2*C+*a5ZXg<2I;uZ}BA5slw?&yP|4tj63Y!v34Mtzs~GT z_g+s7`4h*iY73@yLP`5YSD$@?1ZD(XCU#Z9=r)+yrPBI@6gc6a?15c)k=Vr)ZK!esmon)Zg-3n*Tpi1Cp%cX zuU|r{eCWUR#y2<18(lrwpX5KIDtED8kC1DrCJET*4FidDmPTQt3gw}>t5W%G?rB6> zv3MkNFwei?AVk!tR4A)=OPYv5J7JF59f2&pv1v=`>v&0tlotuD3J*$de2``EfmR*S zM(4;%Q(8E;!~H#rzbtB}nfIwcbP1}bnr|p+K;Q90`*{yJwLxLhZ-V)Ze!n&# zu={so{N$QlEgxbNXB;aVu6ZMy0bOGLY@Ad+Z#hG9_Bz3VvLT!I>qQ+ocs4h9kaDW53Vw)ERU+F_O8C;3!V_NUL8+Ka&0K`BlNve zReBRpL-BBdBLaR>oiE4`C4tc$%q_(pGLbM8>emx3+j<({UQmTFuGIOy(=dX)L6QEk zXY$ig`X?9(aQZh}33?q(nQ{0}#joe~ZCNGfj%TRqSmjolQJg^bar8|Kk9u8M2%Snj z!MWdmLRr2pz|WtU8994*T~nr6En>uR|9X8pdK?!JHVBlCnF=KIrhjKBx5%a2v-4@? zS#qUaOnQ)XGcic1^*68y4vsW+Pwt($KWYlIiq9t&3oO{N7q)loiMj5MVM(0mP9vWgW9QIT1!MPjj}+rc!8!^-XV3i6eN{vv6J{CqC)>N8*7 zgv@r)p$<(z62bK&ju!-(U}XudJVh|8IebCw^dOxZ3l4cYaZY#;esdz%^mF|0U@cOr zR%E+ZHGELo@hy-7t(jjj;4N*xcu}Q>yQGmA*nesIj^`ivkbH9}RG2smO7H;%$kF(R zM=enPCePEX!rHlVT5)ea`h0n{(6>r8(3QP%#4Lzag&p#y^00oAVp*seFmBhTSA3{z zOJ9Ga)@p6laZ@y}H-9!Kmwc+7Xro6eZhSN|ynQjyDU&!&&?9*_x@@SN#RUKI(`Kuo z3%C&ws4q?CR(&}MR(s>C-^iec;Y3&0BZ!A!BZcvB4)_|?)?Y`_Fnv3XD9KSKdVi$B z$6dj3*zmi8Ynzdq`>iUb(SfBpQhh-se&j-4iXcpFYD%?FM)RX^pdHIyTDfb(b&eRqXXBo&7k!~$_~M=}tT^WM`o&=%OiDRw z#Dn0ze69w`7;PvBw|$}=nyhi;d3O}t#>z8LvSs(-MC3OW>GPUE981Y)7JhC^6nAz0 z_|rGqB#z4Mu@2Gj4ATh6T+u=WTVB)@=6;$V@qlxs12C9aJ)%%B9xs7ExO#DpX12l} zYn^zw!G9F3ZSY)6WJK9yrMY9n$5ZI)ifv0TQGuF}xIy=b%zqpL90HBIq%OY(h(S?M z=-KYO6mYe&I@BMVOT`qF27e#)p0=Y~dQj-$1x^N#5_@mUhHS#aB7>l{mBX4kLVqom zSs2@7t%YwJR#Ji0UBm&-aRbr++Vc{L3+Wv;ESARq-Z-ZN%=rU7F{( z*r7#kkN8v~&VQk=#=1~Ns(J*q$d20sp*q=z0{$A9_wV}fp(v<6$$!LuwUoM+O>>t( zYg#U;Fr*HL22#MzIxxX!m(@4Bd4PS#o0|1;-aDLv6FYa~kAdrsymo8K^0KnW{aF6) zet>_fHHNqGukv|%d^y22uo-4Y$*z9rgfk+n%$5r;B7nu1KT?W=`zVVr@N?xR6!B9I zg^)~fmr7GZ{7V+33V`e$Ho1f5hGgh9d{d0mTQFmbu*;cZZ;)*iUM(&qSb+Iq{`{GE z)DX8i?68r%XW~`qPkwx0ABt+-t!QSlkbwRy8$rtK%UbVSLRbp?uw}U@#Q9nfl+P)pZ8S5DrXan~J zDJ4^k(2tD{FgDz_%DOHm_+r|=oq{J}%zkN_yzs28zZ`cL1YPJN^*1}YyzG2d&*NS! zV1h;}OY{9r4dFqTRC93DaF71A!@YGQZuEuLf6oN(YJyq6ORBiOv7Rm&Pd58kIAhwh z&ls5b!@g4Quwnr>{eoPeq?X^3^rr)d)aC`H3DASI`H+JOy1rmy=LM2CJ%V6Y;CKya z^91vv0_a3ba)a3{6O_kTW+a|x^Ah{y?}B9qUajy^rPaD#v(_N33Wb)FBbDo`Q9i&ZfHUdpdUMoMntI{%G_b{R^CN=WIEIo(~c9#Dag_=)u5oN;vQ8pfX=2 zCq?essxpImMZaj^)q_-59D<$d&rDMm>p7n1?O6&fQ5h+B$p4TVfkQY=#!0>&B7;89 zurk7H8U)QohhCXBdSPPWatwj)K@8;t*Y>J@?Sooy>VfcBMY`ogA%B$2xM#=+P}5`g zqBq}8GD5tT$%AY$zWs9lMDv~$EUkkAJ^av?7~1fS@E7>XGUYfMdx6ItmxaCn}fOHL=LDzZQL>l&QjQ>V?7I;hUZJ2M1P>K^N|*2(1g#{1!i;0a6IY!5ix7v z^y$4=u*RD8W9*OEvuY4nM}-O@QkrmYQY+=DdGxZ}XjfHbjhnPAoRXGvshqnB%7sxf zW#VTI-5%mH6t87MROTwfFo-ii%yaQFkQC)SNQG1PBWiiz*$iWkdCIL zy|8ZJ8~!<@#D!V#G14BW3{k^4LgU{nX{74i0eEk_5t}j{MSDQ|ZG~NT#tB|kxY8E~ zYx4HJs`Z5|#J9nTW&~8rF&u6?&D$wVXTxa>rLUC**C)npl<)dJ0GezVcxSNaPKCxzgNekWD| zy!t(5Jp#XLNmC7G)w(aDmwIM61)Tpz)P@+>e&!cA^X6xpSdypCKugdUcXj$@)<=mi z)GgF=ZH8QNLOUh(#L`w;0f{v(L1G|!K0R?1i0cLR=2bn$WQKmL2M*wS>e~U6V2WY| zFWy1aTzpE_*52*g^!*BPRcSQ2YHhX>0jr{|A-Kken!py`|1e^ zk?aa1f9OQ;w93)$`kC-wJVGBnJBTlgcxDQ<@5T%wS?K-70nGPY7RC36=7}*um(4U+ zlZZhuz~FnU*dGRY;j0z(3(e#G2XECt^ekU`MFvO65r|~9bZvZBfCxLegh`|Izj)Xv z9*kZ;(JGA1kpt^GABbi*)}+YX5mH}t3NAMzX)DHmLUlfSdUe$4AaEy`pNMmm6D)rjupfrvUQ_{=ATlKSj% zvzALX12vH9nc@+$m=GN!SBU=1aZq=Fd)MxsY90S&{onvMo(uA!T*5#^Y0mV>D~Sua zS*(m8+h9BJgS>+EU!Ov@+@@F^lpPB;5s0gSLC+v<^AN)Si>cPL66#L?PV2F zz}AAWy_!!`Ly1qcnYdYnAde7J0@KeuoL=!eZcI_SLNjG-rmm)3^@)F9Cb|)LB}=6j z4B*RpBd9&kvE?Ypdeh=-iN-AXy@}2DW%FD986Uxp&IBTdl~!*-E)3TC+kg-%f@sN* zg^ApZqYXfs(|U(3fVhTX?@-plCZln+%ml>@?{LINR*C>Z)HI^_qUh9os!p_2^N4jXv;J`v3>@kb=m*c=9Eu(qY`_H> z#NUkM1j&bW6h`_fmSQl5BFke}Z?!3w*NR=lLn?X`Qi7$3z$BkziC>J}EohKxE|ii? zqa2ACor+!YXs3tGyN|(E4KezWaACzTaoSQ8ii>0Gv12s}9g3S^3L%(&Z~fb?bYD2Z z6?uNF?~xY-JK56ONHy*}#EP~?Qm%CO*@kb<&k>HfnMweI`hHTRyh);-n1`a>e~Qcs zvi&zc8MUB|s6}P4 zw@*&eO;;<_c8ggq@u({@p3B5zggx72#5aeByJIPtMjLcIj6v)Tf{U8VqPNn!!<2X+ z7H`nE{%$8q6Ni<2)<}mi(nHr`+Kc7rlaDw?OYzKT`4{|^IMtZFPBlg><2QGvTl<)` z1dIAb+1&2#45KD>dR%|&aKpRoV1)m=C&Wt6b0-9Z!Hf?FJN$;7Md-BAZPLI&j@|BkzE+BKYN%!=vO2={lA3ydTjHJ^&! z-*3=Ke868=Ay*Csw%H{&*R73R68+5U!i-bE`S6!29CzdeNf!&6 z{3~?yHz3GTRx_vs5dRJ+MfApx@;&;>GLkv9F3&(3E4D|ASXVb&<)7_e3~K-5Z~_9sV>_q9u`c6WU7(boy<`&jhBhN;tLI`d%fHwHq zt!!y&x(CiGy|Qv~rj7k%b&%7MIx)Kq5zOjs_hnm*94MH?o`qEp)kz$~v5q|Ds{d%f zQ8#jrSVh(+-cu_gl(uEV&|cm5nQ}v!364<36piGlx}V3H#(ljG2slRcpi-#PmDE}F1%@5*koT(agMx(Yv(MZhB;Ql_>OpH zK!#rA@+QoILLvdeEyN<2QoP0x7^16ubIhEMe2#ps{zb_+&7HfUNyB%+%R`bye-W|R zqFD4~qDNAs436i&^3Ay9ds1DEM=$R=OQdeCjk1{CTfm%&F+0SurH=n;BvM&rhg{qR zO&O%KpbTDoS5uDn?dODHyJ#uM7>{)Jt?!7=q$;q5Pp)4MKN()%78=j7Enj7&>2ZGy ztdE@S;YmqFIP~5s=f|B|zdnNrb}rC_YMm%K101)sR*&*8`?cE57+YM7@W)q$n zI_KhseIYq49g`4!;O@ABEIC>p5Wve<7yTacXk zc4f)FEwrVBMipAfhq?gv2b*^H8&7>s*^`{`xscaH6D-e$NP4e7QR~SpqcL1r#EufQ z)pp`jzLB8BV37wwBVyBQUL#QDv*Wgv4%AVZW4r@vgixPFEBkZhfRPgSPMnRh)K^Qf z)o2Nllt^wVK6WLu*1DosmkPo78j&im<k0_oj~cz~w#=u-8Qh7{qb)u%C}{gjnyK zPLY=eO16js`x)KgZ@>L2Km|KDg$|>WCruEu&tJc~^pVNf-xVGaVI_c(zOaHMM7ghH zz3aHH!;}{lH3Pu5X_69+`*|#`sWkN=hzIPMIA^fPNP0cyp1Q+627hGJijo`WXcw6^ z&g5IpN((I~>)h~O&}@AW|MJ<-kOG(jOp-^2r|EV4FkX>;m(8IXaq9ZzeS18SY}iFM zpu$Lcc9NW@IwelGu-@ROM{WtaDpSC=msE4f*H=pX0w}{ybCROYf>`o>)Ly1i)iZ6w zXkF9R1}6a@VioBlF^_X4uaf3ROv|zT;xcD3ziH)hLd!yqqv;m68!3R~G>+aX6_V?b zn#;O9fRvtaKNoIDk>iGB}%P`+lbHWLCD1M_lalbgUv8mutEtjo{xvEpaz@-T;|~g=kX-d%Qjt@%TGqkd;D#OhV955zRq0h0|}7eff5*AS6$xMx-gJ7sM5@hMVEAJHN9YJ?AC zwUZU=zO^jo$C@daqrH@dgB)!uD>)@HYBLD0_T|`l=aZ2_PaK46*66BgD!I|giElwr zX!RB$d>}|i1$Hok(vzLAF4-D0!znV#d;s&s@r%j~Ei{Y<@8xFq3)8aEjgzpfI&7+o z=eUvVb!ij0^YaH9AgmqeW3g<2H{$fd8k56RdQJ=6=f~VcOH9WgOXDl*MCU--@T45m zDh8jrzm!y09=MhIH4Ry*{=&7g$`f80INHur7Xr$6yfh>v)s&`sE&6=xS~M2oUATqg zzs|Y_M49|cfqi*J%_kchb(GsAtfTnge@GWZ_9ioP59?3Fb_FN{fuM`!5U!UW{*?F< z5%xtdJ4R(~U;a$(Gk4vqSfc3$I%-Q5%cPvZkCj;HM7eI?B?yVYW)Bh;c$qQ<(txAn zh|a)ZTbG|V3YBI4F;C;acc2y#|G`Q~BxG5wY8mPQ)CeUaVlTY_9F=;Hm0bF}6$iR6 zv%NZnnxAyEaC9Wv$ZEwy+YM>PXO*0Dk9{n5PQC>yW&jpLKmi!Xg&Mj$gJXAMH36YQ zB9)@tk9tqkd?);s+?|k;JrM&hPeW`$3}C*t^wqYQOO?A6F`RTsf|LmsZk`<)bqP4U zQo3~`*HRS*HdSZ?%az2P8okG{azajxeX;RESq?zJN{A#ua*H0DB4~t+_?9_TMnxvH z75|rOidpZtUQ!#SBcH0qRKD3MdHR=cl9q7i&bBr4SwdBi0l3B}As+i%#PxH4kd-6- zf{bu)la`W)t#ux%vpoR`yE#K{E32=r&0hFGS2S@nF~&kr%a)nyRbaQXU9kPlOnp!$ zlmgXaO>)Z`hDNhHW!*t+2bWx%WJQ?rEKy-@oQnOe|Ai(ws@A}ZYTkE}&Y+Fd{kk`4~vmRG3JPCG`OuU1<+9Ie*uMD8q>% zM>+~iw6mnw3lCb2gqTk85K~f#!RN20qcB+E&d{BH4WL-$8Q9(U=*k8QB$#5UVZWS< zR6_*P++&P13!Iv!7K*g%lj8|8YTGYFnV5YbU=z?NokfIG1h5Q`n%|-&T+6dmU9c5@ zdB@9)<(Pf3PxBqrxa%gcnxU)Ds<(5xoF}#f4Mzhuc<0a1=a`BFtr(7x#UX_@g+d=2 zeTxbJc6x8_OjxOl(bP%9`adIA{M^HVPB4w&kbVu6Wre=14S{D=VJKw|CzG&8i3 zPA`gN2EH3}JeeHS>rl|WlrtuvlbFVl<8e}WRGltjats=fNm-Wrg_$xVZ5ajutB;fD z&WzytS=*=cli3$J3>{OmPVien-I+gYZQ&o=)M>Zz`moSy>B)Xaw6S06l8`*erSaXE z8ktpUir`1vX< zLq16RMT2zHN0=koH~C|BRqw_$2uTD9hqsb|I&k-n!m16MG2StAeoAT2~w@hp>UF#7<}I& zQILl<6{*-)eaB$~b8-vd+?kD}Zo(o-9eEMyE8S-iK#i`BNA^$$V@&WUZ+Or`^qH97 z!9=1SJ`zjsUBLOK4iD>+)&Q&?52t!En`!XUR++8TZQas%hF<@fjkU+&et>GQX>EMS zQB0;dhd>QyDJ-oWWR4j$?9hvwYZdgD)Moh3? zR3*mS0vW7o1Kmp!*xMQSt$38`+nO!39JJrPXf$tHu1@!-S|?V8J)}|QD^i)8)CUs! z2%0oDfsXo>&h00gNEuhdh#fL^ zSm)M7jpLWJunjT)jGDnzffCC|+56~c+k(lbKDJeVciBPs{N|7GO($(Whnm8Kyoezw zl+jO??edh-dU{8e89p&M_)nf->k^dAqMFIvqZ9Q~Nx+5tuk$|^6_le^HsodD18C%{ zo_m*jhnr?YZ!42f_R;hM1xKY3YY%kB4t&V_RIZOz?6^n_Hbk(>_( z=rm8^uT`#4^u7krkfcMxL{%jvIX4`dt5_D9%$!JWU#pd{ZxRSXO^BEg->QvCi>Rhb z_WJVbw~hc?ubfMJ_?D#)%F-PN;i$=pJxtu@Em(88)+m}@ zRh)9}&G0Z3y0b({2c^letE}?|g*U~=WgnE1GGYbGT%3DjwO22kZb>*VT+4CicSooD zHzUzK$sc0=ZaV-mK+eCqrMjGiM+_nzha%m;1->p$pJpr6-R-@+-wByAi-fnT6z!ay zGReb!sa_6xB0>&e@{CT$(O`D_+v}bdNMF}7Idz<)AV)qyp#e1WoIN99ro4j2i}f;& z&T|xEGrij@zR#TcPQDa44M`&Kn9x5Lz7heSr7qLv0=bf3`43gaqZFN4<<~tc@S5p7 zN}YQBT}ytLIw1T1z4?0Aj2`eRa5MPpTa00S@0duaYl73~8jPI`3)XTuhzNcY|`FDGR#qS@yt6)E9P0 z3+n*oDfUxEP|V)QNxhy7dGEsAuOfy_AKneKM}sTDq~S99=mP0mYYbRZ!poj3t$}9y z=2VtFmrhlp@QtI2o;@A5cBP`hO2ctW0o9&&_P0cCu!6k8%+K+EdxOTGys$AB>Jb1E z%ZtCmbrqhUS|T!?wVpDvU5nn?en*|3)dj}38dB!{F%z#|h|Qk0>#~9pE=b}I78^Ge z1{_0y#pa?#60i`Q8C@?cr#+s#ov|y*Hg!-o<6cp#{{`;N)G8y!Aflsk*UzP2?oyt~ zJ~32U-j9JI@w!t&Y3g$Qgz?S`am61%_e&$n=d+&fMceL358!^yqh`r+tFD|HPckn~ zDgYEVIJUTV{t%xAJA9S8^++$4g?DkDQLdlr{1Flx9ULnZVC_e&aX+77&ZqFR=H(qx zv&KB%dWTm8&s~e$Aknm-U9a*dQih*l^>+~B^Q9}Ml=`f8KNR|CGM#mfaWPVrZ)X*1 ztv;V)Q_Y?Ovoc@M>LdRK%%bOq8#&P3RBZw`L+wotoPnQc)DoF02~0oG%Z*o)-PR9K}Vo~ZzwkwKzTzyxr9`+zOz%ah9%eW^5wE~ zc?qKZe?6d~$PANyZ;XFSo$Ad~-FCM5y`XUp@ke6vYg~6C*j%8ooAZlfrxJ4*$^u{n zB*M)}5F@Xh&TVjf4p@oCBh`cGle&)jh3fqrGbsi||7RR9T z+Q|A2BHZ&^7kVHYobRW_%{W zZueKuxPME=RXdQTSZ zyKkXB%f%G6adH}(9FnhpiPUqY{u3gJ1o+W&Xy+d%KB1vc&>w7dfi!@;6~^=IZ;C4z z#X%t~ll_+VD1YcH!33dN6AGBY%H`(WaKj0+8^RyUo~JQoJs|~74frijB`=}01~YlS z-Ar5wK&masz$;Qgw@JF>%+4 zP;>kh*^;6J#Vi=dyuV!iGxBqrYG<#RIPWLf1k3RP_1&jt1Wck5dQoBC5{WJ&0Ucz1 z@ZymW8et%}UE-+9*Jb5n5%;1MWsTJEl6-ZK{MJZ&HIZTP-K^47Jn;U8zX)6xOWLA) zx$`XsN7E6kpbC$6WYx0)f}riA8xvCS1H1ArwTq(=XRARqF=AKoETx4mDH@+`NrD1Z@+`rnXz=gu0Hp!yGw5S-kQK)+PkWZ66f7Ys*gklKq=m4XjblwLpA%}uE+1IzR2p`nj z^S#9k6kdhqp&=J=T{)k?F90Vmqc1=CTHvG817AdVK{t0plJ_E`j}2Nwx!($76*17{ zd`Nek*+8S?p3rGMLo}CF>5YC8TETl=Jt|$oGPu>Ux&bgM&IF_~Fm_*hT0KH5qUX=< z*jm>jRUNXdXN0g%Z;K8P0kx!TpwQzE+5XY%i8;iV_nNwux#;BQ5(k}grsnI%4RWNy zpSZrwIswydjIK)(w9{~&Yenv*O(*iMEn&+hO!u<@}8nfEVhgh#fK9x4bn16g` z#rlcj%z2@<9FnB?pz5@4ShKI8nC)oqc-H>OM61{Truw!ziuog|mpY{m*apU*(#D2P zmRPVUPwP*7B$o`-r-ie4i|ZKzX3?b?9iESekdfiKl5Nw6aT?PIrl7G9+*qW^iE;_C zMg^rUHnrV+m8s}iZvn0CIVgN0^x0DEElok zx9DIW_uT4c6}o>ONbjX&xp~Kir=u)xgm>vcqNFl7#eR>bz8{YFl}SXz8;PZ>ZbCn# zWR-E#o0=&|N(-@k#|1R*YC#Bs*DA5&6_=&07%DKF;3PejwLGQn%_k^MK ztvY}b=NsfmaJ*${TM_;LQb$YAiA>6d1UXaJ^p zQ5$i$iW>)k*3Vu%MI^!U6V`F1tjBlnHlpmC4>zXHLOp?EndLj1hZajQQ`|aB&2v06 zz8oqO^dA%pX{4tR!pJwJrt*I)e_9!gcbD-`^uyg5a%=@Q@kQ|PGF{nif6)V`Pa5Eq_li1FHb4cYeC8T=& zd?cr{qlx&_qhtf9vc1N+vR9me*PoFzc2)HZlyYnl2$|VSTH&X^Hmj%VFT(7g6!HH;t^qFiD@6hz&DH09d|U1?Y;mXDnVIJb z0Lgoo_aC78hklacnhEc2u5#Wk;S$q@Pw=Prc*d&?A)263>&gVH@i};8zKon{hc}YO zyopmnXmqFhZMz{<5niis4^B#IZtdJK)A*rJ49d@`jgv>r|Ba|>q)%9*^TS8m(D|B# z!T)XDLB)$1X?#i389!x*ItZwuCuDL3tRDfgW5K8!hjue@B&OvVwtB{&{Y@ft_JXLx z>{%L4j0B>N5>exks$v-5a?hJz3gGLe?52l#0=B5fofB>hY0<#aC>!5;&+5SSU1B+~ z6do6*-a;lQ$JD6Upn?U@-$z(nG7%nAC$lKP{%8q~>sZM-%ChJ;h3Ba5sK<==?NKtC)!2E~KpkXor2hvg#LD`xEkjdz8BLCMXs`}+$`Mmv`o5g~e` zq^7AJg^|s?t0PnM(DzyaZ85KAgp5Zjjfjbh=mCb>E@3b#(2 zl^3)xp1`Vi=Y4IxHDg_PYNZ3ns9OjpOmp4DAkKBRYmNHEh7PKEKMtLpbZ)wedSJ^* zf%oD}>1i1dH4T0Fx#>)GXSu3_-ir@Q3~eUKeh^6Rzx0A>i+K|q_KOB_>ij@NO$e%t zM=Hq;GG#$mw4^>U6Iz;vNLX5wf(B0uzxb*q*AxSO>k(vWAbxJW{T0s zG|Z{lqN~ErNwKP?@mLiEPnyhyLD9jg%9mfvDyNww+8dtS7P4jt@nhJ$H`?lG{w%BDWaz9(K@Vj5(Fb6Ih-Rb#2Uk8q$Y}`3KF&iu zWVfibe}Alb2>Xi2w)3vTmG`x%FER?oG)ZeT#N|^gsN$@MgqkM7Ca^!o{IPtp zKE-3`dS7F=ujl}+4?|%n&X}yn1|I862Dyp3xm~lTCPp`trAJb|ua}Q2WH4mr7ErAK zAT6#t(Uq}|MUH<`egqR!n4#7Asyrnr7z4s&g5IqK#%dRTginGwq0xq+_yeTcrYLNc zl{kZrA}hu-eaWpA3cwb-Zaopz)9^TOpXs4 zkLR)&()4(3w`F==YXjKyJ%VNZJVdR!xOkc8oa({tE%X@&Sa*UrevMr`>V#lBn=*(5^O+ zvK#4NW*x2ja0uyx?4TUed%l+!qAIucE5|YN)w<$uxs{1xh*Pd3R|H8)YN2-AEKRL< z1>_8u?-duv@PezXkKN+t+}Z zf7M8bvUb49a;gRu>`eIDo7rI1VC=6h(=EbWSbDOrQ%I=eS@>Ux%kQsCX~jZfh&w{mEOO{LIv|8R zp;8bbfRA(9*&%FN_Rp`3$*DSZ?=A%E*s8_GE9-S!xwnV2my-7&=KRoUE2i(6;4iQnP+Og_#{LpDT3ysQ zL4@lDcX{G4D6B3TxupcV8}P6mDveABQhsET=laq2N#FNU7S!=6;L#kV%K58pf^)D@ zYGgE;81vMmh)^|}wr<9O?qzilH6yI_{F`1N9tf~!T_pB5=EA^R3Al~Y7N4PM!+pQ4 z=QE|?uM4s02oA7rIt%`FifF~gxpEIE8zm;em1Gy18KAltM5J2?o|>?tUkFb!aRj5< zR9cd3Yl%{AQ65BF!1`87{Gfl97?e|1X{R3kb4lj>3T-G-l7$AgWFB zsJC~np*69F%m9bs8H6qyd~n=w_XXG502AJRv^1vljl!9%>~*oG8xBU))&Fv6A+v$zZX@xDOY87-_ST6|(L?iAPOnR9XAl8^n`jS5|N~fh@7s ze^?T;7N<+skr#&Bv9ht)Q5?O_pQ8VHW?jRrr4DYWD^P6l z9qiNvIp#-;L|C#aoa8CSQH|rIjl@CPLx=qAko<^a6q)810`6Lmi!ib_uV~D6H`q#C z`c__xW^6DuaD+@fJ=$e7qYFqR!&0(yE~*6)q@Y~Inn!f|kjA6#W8 z|N8Y>+~>1!iJl|jpta=(fLL$nBI4%ZeZV>{Rssyc(H;jcQDC!!Zv2eZ>l_Zu4Vm9I zM35}J&zo#~IK%v9kOY#-%OSIhdM@UjRq!G2sT{9a;ycXR_PD9T_&Uv(ilKK{bvLt& ziH0~OBp&a6aFDwZBRLSD5p*^o5ra@IP#(-%D0#E2GDdBc*d#LNs#+j`zMee!wx5O| z7jRQmeV8g=ZtAo9tqv}PW+>WORJkl1o14xgBX1UEN5wTI1J|qOm`${YLXF@3BDsBVbU%dHmA0uv=w0!FXX!uvQi9p^0AM>E4*v zJ4Cd@;wuC#5gm0#_|v;hG-xAjD9ZUJb1RPa$v*G8)19>cT5W2`lR-Zq@obwsnVMGv z<>4cYP*`5mDr7c_RN1v1C~B2S($d!M7^;JtFYUPVv?E*BV^umTK~+fS$RD*uOv0vZ zaXnk;T~e3c@^#(O0)c&&0Zc~pIDte);-0q8`695sCW;|Hb~>$&HGA^&4v<{u?nl*z z@9->I(rUKoLVh~_9PkNU4_fS?WGqjyElyIOV(2DIY)!W>1hlsv=E#G7`dd4rHXn$? zA=8np1@s+TB?ijVlNsm-7UZ`hkN%z@%PwLNcvygvNMZ;A`0-p|HI&+{Oyg(v~mvr&7m;G1~S&cwG|tpI&TIwa6#V<&BUB|~`fpp#uA z9M~&UGL%mutsJ+I>+|ym5G;h+HmmQ^mIsbjp2R1goVo&c-`7sUfoqqy1}>SMO(2xK@B!}afm!eL9p;d-GlQyi+|M= zrc+NLD*qe+@4c4G0wB1A@5{H$``cK4AW6BhihTlIIvQV`9d`)xnkpnQ{)xDpsfRE8 zlI=75^Wl$b&tICwjBuwwfj6e`LbuM?MfbTAOfwcK>B}k6yTCaF*%7Hiv{B%PR6oIO z>j4%y5|_Dei$*AHj4BRu(&Hej^HVhEf*w{Hh>wNaVJj$cq0zaHJ?B=&C15>MZ*(hZ zzY&#PLzXe}hH)t;^_N{%4j;MtB6>Ku)^0p1%!)=nqjzXYYjkZl3zfuxH3j>5xK6qQ zg$c^^Z4wnnpcPlzAyIm)=~8FzYUN9}+ZT5GSS7j&jU-gA`;R9h`){S8LPR;XJM#AQ zeOFrUbEj%lDs#FG#G!b9ky)X1vEUE^iu0{6Uxdi$>bZ|+R0d>|D!icT^Bn7$ z%B#BsyAYkY4iW}?uwomm)4nef)k0_iaLhsTa*rK~sm#NNy2Ls>~qO5PB>hdNf zs}MYW6dv>gL;Km=Dsj7A2@A22MN~8$uWTLG{!Uyaa@f!}qz$C4YD5Gssk>YbZKy7y(I!&JL!c8p(0h|6C$wn450b;0O>Z&TsrTF-0m z$I5bg7Y@6l=9MgZc^m`FWz>4P8JP&KFNHr?@U8#3 zxqFFwH^Q}JJoLP~RI0V?QqzaW3#!hst}#0?Ej2?Kxm;Maol!u(@cz8KZUu(Fr$ZCm z)p}vX=~%14ta`gU;PTil4G5#vvsb*t`Xnw@#o&)*kOT+Zq0b~yfM_s~Tjmz?Ilp>U zfU3OUjIss{+q!ZV&F)5LV)M+7J=Rq?eqT_Mr%3A7e{H=vNy%4aq6w1UYDXGE`^csQlI@b90CsLZ2_1KX|>}$piGuNy1moF}CJWG@qCV*eo&v zBf~kSY6GeFf||Y;J=l`uP$5a%GK`aQmMRF${%~3%`}~O+4b>{i`8mEJjl3_&AqBB_ zsi1pK4`E)do15S(6SAT?CRh@|=Q+MQmHvrazp5lUYU$CG z47mx+iRRcn;i_HjX-2;10utKjhqM?UOeJaniUkRIC1}Vj=J$@J7Y)S}8-l+SjF)=# zYb;L_D&Dz=+HSTxFr9uERfwC|!F_Qcq`;BaDs z6L*3*RUE%Jy5HJ+T_IQ7WyLWJ{lw`6*VWor ztXjSoR4wKb_*TETLqD&0?Dt;T{5#mE7lM1ihTBl(CG1A6F^yq@`5M2zGHl7&{Y}G= zP2|b@k&%@1AzQEZ61LOy1L9II;bXtR?r-2oRKXAtQ=d4@YnyZ6#6`No0FC1NhjAnC z!sEZ*UYR-geXz8fu&q-A!A(_KGP2tP++!h%_J!T~IEA_I}>vzD&TJQi4}kF{x#$mb@2t4FDBVq9u3DfDs2b z!ibtHNHf5z=<|QO>X708Jy#rt>P&B~`hR~Cq^AvoU`N35 zGBG63@T6MNQ6Ka$LHB0<5e`<+uw&F6>Z$ZYwjaRwQiC^IFig3PD@W6?MQRYaG`}B- zygz`}#NQx?Mh(Fhcjbx4*EhQF0lq?9(87@`c=qHb@pTG2eO&#qBksW?XO=_96?R^q z=7pVFUhL&$1h79TCT{9{4uh@~COW}72Qe~njV5&Cs!PRc1C@g29PP>Bc<-2ESc-p) zc6Gs0nab+`D3t97L#Lhn9K|5hs&S&IPB(ti{dgw{X=%Y(Sum2MsO7}p*~&uu$&6?3 zbp{WIxhzY@cen|@3V^{`m1(p0wX0JTakj@|$<=tLl;$X!8AJBwnxyYT#IFhQ8<&FO=+wqe~ z1!sAD1TD5tTgtsq4aM`{KkFmv(8IWWNF*7iY?J!WnQ0 z1BiEYWkY!o!_C5kIZLku7{e|%oU^>u%JGosK6;B#R(PF&4=284VyeQ9F+Vh$RgWY2 zw8zp3)$sbGt$FRZCJ(dw6;5AQi3P&3_Tq-VDOuxkS{;cF7mV5*F%e{E)yxcem?g1% zjda4bHNV499}7+won3DZEb3u7K>9cnzF8yNesSTDgrCC1IXL+NrXXf{&q$6)^M^vi zZP&iw;3xbkfRnh5obtm3U1DJxGDoq7K3iE;>(XP`xZ^f`j{Yb+{sdyQ+a1FV2K`BS zelay=EoDux-V!a?KZF3^9C{9w$~Pe1`whb$$%*p!UNf7Udk}40A5(@Id(^uY6c4E2 zFkS=B(bvN{$T-!~9h_`#OMd>|R>4>fewBM&qm|C$_KEQbaGb;R{@kO4w<277zRfYk zEn!%(?nrXbs9(-4M6ES?Ydpj@R$mF+qv=&@`a%51p37InNTg!c!w}zwxU*efwgkkK z-r>+b-Kw6sBkE)i2lim@%a&nDl$D8`76G`0!py|82L2zFWMORZNUu&-Zl|;atp=Qz zF7z|f6lvX)1#ZOq3ULcOujlymGa1({Fp6i463)K{f`$taH8m`?)Xc>kqdBx@j!*K5 z!|ClmY!Ti<$X+Z|k^Jo1*)%euu|35evE&_L*qz?J*MnEOuD}=~YyWbj$th_xvBZzp zh4;lP^w1MTjeJw4S&xO@4E?<>u@InGmqj%H!h9D>pYX**YDUz?V|*_~&QGBe#!T%r zN=~fJKFjhDdWHMpkJ!azxS2p^9x@}%eeHAJ0tU~*7$>|7o5W6))Dh9&8xF;PE2{zd zd5?AG94GZ!k;g;0(lB*$hMDL~l7QT*`2fYQ!tR9kvR?CqAl46;xR7iYjQWsCeV1lnz@OH*UG5YkL)eKLukY=Ye{UdH`{s}()Sy^q@*aH1A9dX8b zV?R!~NdIG@lp8#!R^14-B4&hw7iifS;Mh6L#O}s^gyKf6YVWHC@hHpo36&^&FL+~=e}fH z`0OifD(RI!e46Pr&Y>@`hpA^aDZa-cSg-{SjGwp~_tYj_4BR-Jt~~NJBOp=g-B9$w z`7y^c7Lh6Qkk6M8nfQQ0II9rg9|*MuM|pQ$ z1qevWg|r^>wT#ezwqeI^HkHuj;&&6=n>5ntJidxNcn=JMp1v=;$yOiYu&>9eHm_0X zyF(uZYLTb?DS46B`WA6C_!8`AGTZ`7aT?+;opF0A7Y->x9SuCx)iZIt4N7FHX~B zRyitL{&}*sK95!Zn0qk=jOhIE=c3$yZIgP};XG!&y?*aEy<;{(h6%`g zEcifIR9`r?TDluy3ig6F+u+>MmZ%?TpioGaa>28XaWR+0aE2r5PQo7h0{xPCj+Nl3}Ao;a0Pp8vbD1`4Jkftu27k&M^qja&m*n7RyMsDUFBKF4zx>mx)nD55maL=CZ~@9IbZg_A z9U9~*C31b=+;zGLyk!PgWPPB4lOEBj1^vo4U{WM#{T+Zizci`AXj%-t(YYg1jcMi( zIaRPdbeqajH_U5h#h8-?1oBGuoG=l1Z4H{G)!HH%^6?AZGioT@xco%!V*fO!^J)XvJx za6?>Q)C^8_tOz`bieEJlTL&#TW4g6*%wx19&G5?`xM{7uN?Y=V8$hqD(D<1K?SCyV z^v>_>L{9-`H$2NFDml(D&3kBBA}z8tQ-kbH#D_pQ!?tjbMr|wTi!mqR; z^D=eEjce~<8Bc*%9$%XRbQXs#9{S8S54^OS5ZLLq#ko~v6F<<(Qb?Z_jyFOt$=1M{ z5c|wMCoM&MekR4%5t2ATQ5qL!yw#3d=43Nzh9~CxKb_2qo$KG)j-tlL|6UB6U1Q86 zMP5^(Wj#Xmj2hESjk3(12bz#TY<5D%7jYM7Odtkw35&g1hjy8Xk6 zqO{S@=_|~y&=dVGrV6Wx$5f5;?_S94E_?fo8`T0fc@NG>96ZeChiP8|Nm3abnusrD z)@7b6_h0tc0};br8W*RhE91=$tWg7Azw~s}nO*=4zcQP!c|E9`f!eyVckVfN6bj83 znqtv`xr&Q^eY@)A7->zMwlPY6&}?VL#7tzSzZcDun6q$Tqj3rjpb}o8E)T!|8qxKr zHR^~Cy0BPOTkg&PQycNO?QB>0-HHPJhUfX|VF8(9)vZvI`ulx_7>Ld_OhR;sFm(I; zj~%if*MsL|P+_0sz?{p1H1i0_$`sBz$YLu^Z$@r|dklR4RSg6S;(dU*L6r+XRTZsf z&(F?P`Sq(Ed77X4s5w)b@s`m)HD`N02Vt=O15S2NjR($P9D-CovHfsed_~^QtICc1 z*Rk>g0Z*+6y0j5O# z1rI#=ha%4d?%yVf=W3CmqA;_D=E>JVXCPnTiS$5XscZK~4vEhRZy}&6pnW-5cNEwt z;7rmtMS22dMTT!bHr4A%l&sb$m0iyv zq5p|gZN)5VeP7FMmA&3V5d5UJ{yu(Tlw1kJdbrOrnzq1megf{YfE4e=mWt~FJ>{%B zzz-O*RNl00>krR_N!1-)(uhLehFYXo(M0J#5~>uD-PfbMwlEXL1{kVX9+m4AQ` z$6a6po65CO4K&RSbnau*<_8H5?Mgoe`$$B*l3KITX*)#{kS0U;5zk3EG||d-bRg zbGI*<##@pp|F?!b=wZ*@R$olKF;`&1ht+o!g)SOMl@-9ati{>Au;fE(2~wIvmhQ3GG3qz|gl7@7CAlhNqxXhmx8pYD<ppR4<2+Ch#5jW6g0O@N!czXngvPwE0 zyd_`G3#@Nh(ofBVfkr3;FR##MUr&)#PyUJKZG`8-OKpc3Z@c4$Yu@}&C)fs$AEVHS z?FR(3V@d80hgi!6@ycJWPWMBD15GLH*n0sFY!J|!bfOiMrs_k8b1D$G(bqn%50w5r zUr1H_fJ9A*Q*zMBlB(&==vA?L$R;C7b0uEO2~$km`eQwiWDjaXB-zoNF8v`?&3V(b zFkzjULxg0oINF6k&p>~65t0O}2ZGV0nnk7Y34mX}M~ankTT+HZ(BSb41KlmGv?d+C z0F=?z3i)}Qd*ynx*as6r43IeEV89kiR02m~Nfw!EO7+p*@3i0vJz5qf*`c;|d!n{F z1~0wx--K_D)&lacVP?_j#JKy~E*6%_x&KZIsqH&_uHpfF0l;M?(2kfcEIZNlCj<&Y z84n-@0e{&5=#{5`pNL7`u@~}0P^34)btlpKcT)tr3clJI1h`SL|Hq-K1N^9 zl)jwEjPBAG%{wp|JMuE`NDOm0^bIP$M%BRtw1w@q<(Ym)2G7zMRIE#Cpo(dSc*VBnLJjT*_ zqM6Rf+)vNXk89M!>{n@GhLfYzS@GTFfpttfCq>ei(DbNI*wxGG$l_v0gE7--dC1x^80`~0$(iufyBe$lpINe|mspeZ9@5px zb3)U4xv5=XEO~j;->x>w>%!B*%sFOW=h)-%U}@mue>H(VC&&WTsf*zT-KS;m{T-GtxlMptpKk|dl(}E=~=M&x4L3`8Vt>z4R*>L3UZtAuD?K19@E-BXBvt@05 z)4ZJf$b@$#c|pbn5erMMt!x zkmdaPeQ3&&=&tP}hLkO@2fZJb%9qsoxmAn`t_qM4tVBahi4>CNGgzYuV6+ZMu+ZiA z29(tM9um8UQZ=D!P&ezU2F#;U1i|`=$*cbYC@br9f(z9D2+-<9w%F@O`u#%=B$lx< zvY=smY}a@R>at-km?PB*yT;@~3|$L@Fh%rcuq*1j>pxhv*B(hR-+5XFR3L` z_dT6H0;5FmN8_?e;W;Yl3~AM?vcF;aMs>~xjfg_5Ys=@rm(VrsUU{p7X-kshxUSX0 zRiex>mJ_Ld$hK|NPFjpjgD9g_m_TB65x`a@w7b>NqZ8fG*3?nXA$Zz-d!e2mmX9_A zxB-)Cn$@Va7ev+G<#FE~3v#FEAlaaecLia0Z3IY^wkE^sRcyEfwoBGlo$7imzXd+F z1d{VqGGZW*k%2d9Z_;l8{Ask@)_vBari`4L$N_OPGf`+gCdzPmCV8kZ6;MaYPlX_R z<0{tD=zeYJX%77+xW%=N;*HBZo6@&sp3L(^XxAEgM0nQ=41-RJ9{u4Jj1_1UaQ3#M5=%YJ#K?1`tVEIosWP;0Mx@$IM|jtskvl;*5qp1+!l==NH$P>4Z*jZo$`9x} zcUR6xVF=ft`fV)7xHXow8>s@G;9ONadFu1>BABEH$IJcZ9S7JOC^_77Tt26Cuq0z@ zKMb)y=Tmd((dZLp`w$Ze4uROa%FeSiw5U$5J-17e0XYg2`OU&`UtiXZ91=^fbX(aF zQThTy5R{xgrgwD>jo#VakdgmE2qt7jA;?m(UiR4?_Z`86-fNSr4L{D%&CI>C_`cty zGxd7z#WU<>cwyONpb*^fJZmBRsJoeRU7^xMI-S6#5XJ1hCG==mr=r<#(WWVF6r1~k zgSfP*ruXUYG7MctrSBnb5I_y`(t+7^4CLCSSdj|<;8&ocAMr4&um7dZJDb>re9!lX zRYTd3_FTYm%LZsAoznNgtpA4){vnq9R^;?FmLQJ6?ZVl@3n9b&}Vri=7AcvtLX9_~hC+_FFRh1I{xp3_>{Vt_pKLOxKgxNm47c;JwhVV2s;e`xOyJ zcD)itDQFkgfD`K17s>C?lmE-S%z$1iP~F?X4yeKr{_?>%gO>&C&k(lJCLfyj`yHYN z`->R`0wUYkn_)sl>$dn=_D)Cj%FNu8$^~GagUVc@x<`*KZ!z2R-&CyeDv6+*ZytZC zswrq+L7tjfUdA|)f$Z6c3-H_>J#G@cXkUpU9Hj*w*Ga_8)sTbY!fkbY{lI!5>ZGS-)YC zVY3Uu)V>$9{#V^#wDlW^uJt4C9KCLFxE5=aC&OiI($P{(tl8&i%PEC*p8(y+q<1)d0aSW`lbN%6%OqC% z@U}v&-HQWeib< z+N3o4B|HT;FUc%4#+vu9+(9?0Vy*w;7S-N@%mmv)&wj{UeP~Bfdb1+`*cNnVpZ_qj z2`o(z(;42bR=Opz;r(2fAHXNNK|W6Yyg57`+P12Qc!ALo&PLv~)yAHV#qkspa!u^~ zwvjsJ0sQRKfi(porR%zcR41V7s z=DYWbxE^3Unhv<5^1|)HWsw0@GzH36^oNhe4d_+ zZKPikT$2BE#Vw&f@&Qaf{%N;L0%L zDv>V*8bmUH{X4w%ll9^|Tv}kwK;O8t95~>Q^d9^p{_b9lt@G269ox|84Np12sFSI& zq{?nZd@JCR0b(Lr!Gf?Wa-^A%2hL+jAIuG3wXrbBt7^_h)#>2LTf8*F7;@O6gaus~ zVYNa7cSO(5z(~SjwcM`_j7#9siH9DpfuqQsH(=IY#ufpf2fz@aDeeOEb}3;vn#JJe zHg=I{S6X~(eB9KGt<@qT|TJkSm=xJq8ty4no@a%^NmAS-kfJ zf?VP09#gs-OgDNuhV+wBe%7xRE&SJ!ktx~dSmp59^%n{L%#(Vjcreo~ zS_Z>kwWl99zUu2<6y@Rs3fJJd6soarcd3tJnvL{~JzQf(#gV1I3v02Q#uAk3UqNC@o14v-K*~qg1Z<3d#arxObz0=(4=z@hIsYBzj78| z5~Ygj3tPH{KwYTedZXmVa;xJ7GcR06HLuh3LHnQQ!f@Y?jMskWK5v`=#mg+$Okd+H z_4&Z&KVvE`g~IiFO?2Z@(}Mk;M4VP&)$}HowYlTRyT#S~Ic^|{d?6%>i#7qol;#B< z8c|}Cjb=`VBzNRLfAEr7VU5*<68bb@4Y9;;YabEU<{Wg`?ve3Y{^8_?^OwUn%PO?( zllSDk{tlMwFB!CEYe9+D49Q{JO;+TH>WGCsqc7`M4T3DvMT@t!CHKij)s<;y>TE8( zD^leh9~f$?K7saBUPa>pIQ1a;&Dz0#5*|8j z|Mm1JVTI*!PRyPmZ7n0<$tGIsf0U7bR7Id}n2$hba3G~u!L;S5uV?0_@1CofiNS0c zzv~qPq}j8=5DsdX&~a6;!Efc=V7ypWga9#aHt*+1AKRpi zqVMFAjJ--@9x*gf?2sGiP?EpGLWM-?ef#HURaoV@w5agw0BsnTnqV2sgp-46)wl3$ zr&`S7n3Csp1=t% z8&c@NtPE)Qp4KbJ2+E|1%`NCgIbupKFE5F`AzSu9<`ZN_fM$pxog}r;K{bJ}` z1Jzl_uv|-S)wh=2LZ#3c>GRLe-9|;B5aVfIGS=vAWVz8C{XHrM8E?xsh0wPaPz?sL z+Pa@uDg$W8izn!oU#>zpqF=f-ku}yJhusc;%(~_#)c{5Tw&}$LVfg5%W&eM}Yq0pt zBw+n}DR&r~TVX`To)l0GRCvqDt!?PL^bX>HyhF1*1m7Z1kUMqhFC>@g7g^67t#v#j zzHI2+!pc5Qh%d3IB*!H~K#c)R>Z%0rWppyStB&TL5tZogOeWLG>L-3l5BBHMa0xyX z+tI)pKb?5omn*D@*nH^yp7q33Iu_?lfX$n}FTzeVU-?nofQ<;uSC6oqAgoBpo=4`1mm7H#v@VBO*fezv<5;*}N{qkqoQ`=ZR} zNa`*XlY;423~|$7=u!O{MZOiH#D`wK>#5n?r-X}gz~fq0E3oN?B|}A~Tnk9-vMIsz zeVluY1F_wV_Rm|ksCVzIaE9r(!c!c+GJd~RRU&rtFoRGu0ZZlO)&sfm;qG0+gk|Zt zH*(mVSxD|M5LuI*Y&ZA=<@N(QkjA8<)=5?z1w{3`0)Lv2B#Y{jV+OIhw$t)oMPQi+>uvv$p+*ZO<~#JDNlb9( zqG{^Sa4uac6fr$zC!PLfsnNaxh!A=_zEyLwXwJS!ICkq2i5B@q00h}ajp)cljqQ!K zi=ZFBHXs_IZ*o;8o-pe;tAUA&G|&bM;p310#Nb6m+$5`tr59BVfF2!~hFj}l`Ekj} z-0s8Q$?opPs4^6Lm#3O>O||ZNGDZq9Q@BvERdEaXGfOj;o;BFjHEF0 zNe-VDBJ%6h={8U$OZw{NZN6KmXhL#y_-EDFS>y)wm>)dkRQc=$>Nl+w``SBl)80JY z{erX++Lxr=UFw_E#lCU!{lDxA`i>8cKaxt~o}A|66!2;@C#9BlK70!Pp*(Hx_|xnT zV3%Z9AJ|gwg23`8FVvI|#gpHniW(}U5s!9DtI+Hc`kGICD2}7bB|8k>GEndzBp}|6 zpy-0(Uwj^iT|Mj=X0wncHg0LFjuw0sF)Szb?WDl3-;-yoJ$ChL_~+~)vDX-+VO6$i zGR5jA38_0oi^mEo=njC}S?${+nmpye}e_d^KSWV^4)N?BeXgP@$X7Td;Aub8v`xww#TV z%w=1od1Qw$hb9fEB{J<00sYs76RZeYStxeMV{?J@{4WkEQsryNF|}{dG~PL)g=FpjE%t; zX?)o8@Hy?7O&ZNKY_b8`KmbbA^_%*wTUTh9 z9`4j=y*_oJxkL0&_?I&WR9Ii(B2@CXkpyBSh-PADG)v&;;-b(KX$%)n(Tb;ZK z^94JU_CnZ6CDqmQqTkYsOBqK>>WJMB^Rra30*YA%W6?dQeykD>9dcD-$+cbu(UjyccK6yJk6bvrN zSgMYva<{SE+gk9P%=JL=r-%OI*CQ7jqSt@N3{B*u1A z_iSqRi0`oer4zdUaMLRumkFl*w~o|)_IX#)y!S2JORu#n9=3bR{nEnI0^)C3D93(QmAJnl8JHEC*IG#l1sBQaP7~ZSFA!4%FoItHZrgO*^$exWB1CBZep3W zExD({>*1)RHiO}V39XL#U|;`=i_L!s3B|voAANV}4300iFH=P9Z;S|>o(Ro#+*P2) zA?F}+jPu+`lM1h`^20p`SMNJVre)a`kS5~dXOF&0UmM#kXuYGba(F%0CfA_XN=j(g ziC=Z+|JqGFc_?~XJ)}6kuufe58zuWm?MI)-x<_{?MJBj4i}VLh6y-djblf;|cH)qs zu<+fo=)XLMQhZNNvS?7NlY4mMC*!2vd7qYFxVdRm^4ZzZH@n_%DDN7G?JhRgP_aqb z#y$BeFaF|J&I~@~VV9l7e%^MD(fCOTh8v=l?%z)>H4>ie=#&stE_B~(J2mgIP2|7A zcKSHqU9+82CK(F3kHceZQ0SIqO~S>D@)qlN%^svn2A%GInpcf4^`pDJzz~5T@WA zrT=GMa9VT6g2=9HQ=(E(ib1_G^iPmNg@iVvY)e|)vp&C@s%lzw1?!7UrY=CZX`a@JahO_x6xx+;>ga zzA8Ap&A&^?uvVX@HaC-Wid}Pd@3^tl{5KYf_;4ea_yE-D+pD6@PuT zkWXIt*E18a@<-eM7IRDZcuD)y&wiiiYUA(rEE*)nZc??Z2&By()9GIpsaX9tnHm0k zciyA;Me9I5PtonZL1y(s^_eQOr`>a|k=!zudoRAFtsYun9Gd1j@Lns}(`=@*r$g-F zY?jdQJWVk7;E+AX7|UioSbvx@w={8c!yKDQ# zcf0jgtI&%>*#~x%ZJd3_z`f8ny^F?C#=6<3@cY!n#SIJ!i~`@5N^@lWri5lctmUYP z8#PnsN{{Z3c$g*apE<`SQ?yA?=Mvk|)%qi|<7%ZV5!7SXSGN#{@Ex!1tzs^Ji@I|B z7~H(m_c|_ecEQz~si;Hn`GXv_zVVk3#h8()pI0z^t6+hxh~y?Tr>ZO=$-t?aq@uJs z_V7#;;jC#O=W?(lum4AZiC=T-oT|S28(qc$gWIz*n{Iek-nNuJIUjt3qG;peBhgtE zId?SW@5ZpjT)z{$4U0>M+wf%u zsy{p5#ovPw9y4>UV&6kv@K3M3UKTHsO}+E!RgjXa$}QIY{;cbfdYW-_i60C&ihs9h{{me zTJyr5)OqTEs;ycbbBXR2Rb`e;zrWmdFMZ~Ch&5mM7l&$NPxd?y+5Kp4V{v{+NT$gh zhf9|IGD#gT&FIwdc!jQL}Mcr6w@Yl$VIWT%=e1^e$aW@p)h!;-y_o0fpdb5AQ2E}75TZ0Zny$%@MqW6B={o zse0G*RqTkW=V5U!kCv81dY8o1@eNdWwc7M-u!QZ|G{c|11_{QVc7k|5UOfQaR z7MsuoLk`INP2@N^apB8gubja9n}@g_QI~cfx=0Kj8@;ycbiBbGHcO>ko!V*rXeOci z+Ud7LlAkZ_`6m+@qrWtn={|O*xG(NsMcmVy$67BNPw05f=h_}zGAwUa75bU7_xY)N z-RYMrb``(oX;}a3Aj97=ApV_+eaTte-!j}{)5)FQ6|Ex7!DlVh4Qkjj@4F2BJS;k_ zM_NkU#UQPnkQY$)fRR)GU})>X=!cO9KbY?hV*2lT7S(j=$*1F*?%Z?v29JnF*Ead3 zr{x7XeQuM&vA<4m*M*NStx(e&i|mhPNNI)_O35p)zx$VP!~euDCq=!L0~x7lg~Lcb+tik!jPZ>HX69b?Age?y~u#K&zg!*`JrDzQsy#Ro{zQHn-4P z7+2ZX<1sHZD7NhL=GPhgoM`=|Oa|_OeoKL^%p*I5laJ)yTqno&2bC;GJ2L;B)-AKR zs;s%si8?>IrQd6mF^m*H6udm9VY;^bT9=>yw~e7e@AmyndBQh?iqFT>+mbKr&tAHc zxBB|X@&_i`71>+8rv8^|n(i~+zs_zYetqb-4p#=pqtVyy9?P}trfN=37uBu&2-2yX zxn}`NiD%~ZD^31$Y}v~sNLdlGXzV%bLAukPM#|c}A=LW07RLaS6M0+Y=fI8%MYk2j zuknhe*_Bgok82k*r&h?pe9!0Xg_Ey$$_@Z!frJAwM{GvhG zVM>(y`}Cd{Oy3XhZsN_dt@JK7n9>m8URkp5tBMfbz(2|B@I1g?@OAu$nUx3Do?{SdrSz`{J3;$Wc=FV?1{&FHn@I;|wNWq%m>+nC+ zKSj^~$uRTWbvYhzl}GCD{0$2Z%r{8;r{OStIv&4c%Lz}JssKY#vb<}o4DB6`Uw z$;5Chiu>@LU2AD=kEMUraCh-rc6J{D14t6@^qzB)g{F{XRr3hVysvQo;*--FCtIuF^A zlVqA_I1w8Kc?BS(wbR3DiT)} zTncxnmr~~>-$%do&DPsy9J$V8`b5b%%QtbdJv@l{zoOr?mG{niMNK8n3Z-_PhfCHE z2*mYzUH(C3kPg^QIxiSIB7HBo@@sd4SJ&shNGINPL$wkPFe>8vc=O|4`@N|KN6w5k zv{sz7+I{7^&B4L*>%LD09cq2(Ar#Fs$qzFgKi|X3!E*P$>X1$Mh8y)BHtW7k%p3}g z8)cRFmW?hiZWeX>t$AW;X79C?w0BY-aSzu^R))^(QoZ0+v}^ioaa^O7(%E`ZJ4TZ( zzU^1Er7FtSXY1dyu4SEWOL%*VzPs1wa*gm1{?q5PK~6sR0^c$5cw8A6Y)oTxN@ub8 z+1;2C>)K#`igq?Z*>bgc$90y2H>-bIqzybBl{@C*F+cqH7=IG`M%CdvrAvaEd{o}h z>p!l1^Q)E{71DFNpn9+SeB-HFu9P?Q8g!!*kn>HFgv~c)1{pnd_9zRdX%*WZ-r2S4=Zm)(5Ox9ZcFReLKVwt^l z)_K~#`}EJT+KZ2zVsYRbzTZTAWWIWO*-T+*(&XE3Bbh*b(mWIUXU6!J_JG@qLczsC zwbuf_PjsEMDdSn_togB!@sUiMG*wrXf9lZLPfCtj<1%@s*`BD7H~1}@;p)}rDZT3Y zK`*vFtNFVL|JS333ODhvaSL~Jwm8${J4tnVY_kp%a}Sy$uQ%LV?8)c9w0m!0lBCMd zMc&ErlV{GUbWc+CbuY-B)}q{fGycn>{E>2w;BZjV$^8m(O(~soLLPbDhPpfj2V<4L z#O~j4)R0{{lUpI9^}~aHrCx_8OfKeHePX5mhHehnQnn~uoiSh=lesKY=xXDBuIiz2 zvh08&!>sL^7vp8Nx29z3$0gMc@1m^?Cs<8b^EZ0SAFLit*eUOvd+@eEXzJ#(on94Y zf@>SQ1_Pcm7^Q!e`f0{;JD|KZML6|?VeP9Yd}9pW~2}$`#JK*Cg7eoU*&}@D-#5g^n2a-_CTD zzN%kU-@}X_9NU&`zsK(3>B~7iKZf>_yGHKcq^}9K>|e8SIB>M!in^aN>ppf1-muf3 z^Atx@j#8Nht`A)$LU!g@URimhHJGXJNlVo9gR7+Cwv3n$t~q+_YX|ZaU26^oWh?gS z_!o*@54kut@N=5mS?c$$(5E8Np<7P-G#6D7WO zuUq5R58?=0gkr$Up8KB4m0K%VbPi?j3(D0UlKoYaj25tqJEz-n)}K6wJ#OSgg!h)7^XGe22HK z=q+WRrS9G)T-6tTEvfkFv;6N7#;nGBV;I=%vVFg_NOX#c=V@oAo#4$IDBmyH<_k`@r^oWt~?C>X{?0U-ne_ZnyDby(epF zBG~-gs%CVWZxg+N#YX*Y)V_wuvjVx%FCUuszAbeP=)c{ebVF=(2{!(eOr^~(@OpY>LQ>H3F0fmb^J_3G{7BNLazV_CN!KP|be`p8;5Sn2TQhTa8M zRStfsSog6?uJl(uo^PM-mU7TgX_gD^;T}8Ddi;C(?v|FrH{MINTk*_(Y;o+@?Q3Nu zmzFNAG#46;6l%%tq5PcNx*W)HYr0weMv}-;oyI5oZtsxz@ZwlME6WN?)sAf!%oM}L zsu>mo?n-2Jbn>&0{W*GulrPTtHJOrAr$n4SDXje@iJ5oHkbCL%cfHazPZfAuUh$mY zW3ub*<>V5V2vN~{MF~p1j*WZ$Oirz@&Re-YoCvOX$R?b6=LbdMmiVXNM;=dCmkOn- zwRoI6v{HAm;9NxN?D_GNrBB71zrWdWUT^AC!fVep>#jJ_7M=y`MarU%^eNFQTeWkY zQf1ed_4776bSC~M9%yEJ;1*!oC|Aw4DXm8aL;Davcx!Z(}gVxo0$*gi+J zpEa;6W#5w*OHUl7pW0Rb)sQgdDpnfKS^TXzn(W-TTTOC~ErLaIw?*sed#aD#bDY<) zHhX@(C2v`D>yK-;nox2sCz^X=%D0r}dyZGfFH%tLar`%qJ2H7yu55daC`8zhcg!90 zo%{D{3Zz%fal~$QoVp^b_&$H(tJqpHqj>+}tEH<%b==#J%JwC{YWB6yOsXtWmb*rUy@n!hLsh0%PK#Ve0ak@=5_K6n=#*$_xvH9f+?Im zr*94OC1xBly=8pwOlz`xjC|MjO?OOVICz)^q!jrCsn?r$}#<=9?Ffj@1Zz zh)ajcN#F9@YiD%V^kvYUOO^b~Cq7?l-uC#Qet*7^RHkV1$po%XZ}<+i{wKTp@%O3# z3;)mGDQ|DRNq!Wgbe?m~Yj`Zf(R-(p=(Z;$Qp@&1U`j zPfEFqw14^HP!it(H99@F_(0|!CB3F1wmG+l1$O1f>yrmIhR3am=s&ACT9RkSkooyY zrJIz_X2*xQrh&rBTbdryCAC#^`VIcQ>)AYaI7NDkaLUyavdQ^J^4oS5Tr>W9p}c%x zX)wDzysLPlVON#2XOQu!w&*DP*5J(vZYA=SKL%e_B=htPd=%JV_3KTIfO(SG={h2% zT!Ivi?^QPZ_IK4m9sUf%6Ac-B54%m34?J%XoBacagE_pTx^F8E9QIbfd%oN|+VaG} zp%AfzD?+c5n=G8Hdc7H+`r8Q9w}-}thp5~78~Bw(MgO>$mv5G?=GD}lHs@eep4Gt9 z^u_4_xmuttc=f<)hf{fj#pBD}8yU~4#*c@4ir+J*Iy?hzF-G->1Ukn3S{d>1t(b{YR zm7#O=)0dM!6dT^9E8mKA3k!>n-}PvsFp_D<-TNQ(gyRMG(5_{(YAluenFK#tINzB6 zX`txQ;QkB!lj}kAj|dUzguRrB#&YnX&1^GasFkTQ_+WMeeUQ75yQ3G##97*$sB7 z@Lg5BP}OqpfqinD)6vO&U6#lCPvjZD-sE)nzvh7(?w3DF+4PyYT^e>^eV=_Lck)@~ z7pVwprVrOk1?^tW_cm0$-z)|LTf}`VKg$l*i2wS`VIds$*wgx@FlP-(>4C%6KYFnz z>LH=c>uj<9L9YuNwGCWr;#C*ld(TkpOH8;d%~!_rRxfoHUD~+m=v@&%fnVwjCbOqk z;|qS@pi|yAEjO@z_48r{Eo2kj)B#qCpYdTyC zms+J{8e}tN$26aEPIrjuqwn4P?$MOf&Rwzoe|v7e-_SPiTjh0%TXq|>vt3yK<3sks zy_nY!tFRl--frT4_oWBWdrXtZp(ReQmc$1voimg>g& zSmEl*_I>Ymg*__^M72me*0fbK=_Uv?{f06n7`)I6mar5Gi(k zzLULj@Up32mhEE`S()O|yl!>w`2*Wh3kBsQTN^egeEQiq=cj(t~& zb8Q>k93!`f*J0269(4m!w{A!IS#7SO_|Va&>(yI-_r<;p_toI8X&m9LK6uRe!LoXv ztj>$Dcq#ddEtaLa{W+=J)Q+a)STpD1sEOl`&(7}-%xz6r7hx_6mo)PF$WvFs<=1qP z&NOfOF3I)ZaoZMC#^5;%&URDsZtk%ihtooJ*6y8q_Kbnk{9C=1zQE~c1sn`Jf=cDI z*Z=O*t~_Jnc?wpb+*Lom3^L{VqiKe8GGDnXN~vkfm^zjhn?)HY~2AIM$1f6 zUt0YFOH>#g?OZYf+9I~=8`b_DIHvuszw*kZgH>Bov~Rl}{UzPP?q1tCo)smj-@f6E zKp)BRD8AdRo0;>?Ma!(>TK>kQ-*>L_*9{5_yBc>0&B1m-BCr3uwMH7R_5<5yuYn{R zv+or-`t!%9ElZ+rE*-BAILOa^&*`1ZAu(zGmltdfYmFv4mqLx1&F7_0dXwpseH5>6 zig^+Fv;9wWGlJwm#ip>Vzw4*PjBY;2uDUrtJ@iqovE);8o{!V9|2Q7B>xDm>ejB9!?cu{$D+&Wn z&K8w>BrZ&w%XPkb9nE`IXEmOuF35I|>-wBl8IP%P!MTfN4!eA!o@d%8swAgt9V_7c zBXIk9+p$gQG6Mm3S~uMNfX^a-*!Mm%XXUpZ$V7vo_pev=1LvuJU{& zan7Y2-sXEqp}Y1}SHJXj^5qR7!+%7_pWgl&?`s>gu`5^Fno0P4oM8$(|3u2|ACDr~ z%v)brrLPpHN2|Ua(Rfu}BFg>W$vMWioFyS!WukI)*gyT6B7Ry8lUXgM~-^KTn#(y2QCw3q({6H}HF-!MJj zUBlOEG3qPx$A!E`4QHOOYC1=~rXP5DBr1J+{S``WDvs6e{voqN=}38_MtCusW38i< z#+zu(B#3tX^Jx1|YxM$-toPPSw0&{!^zc&x7uV@SFWu8w!mgzn<_72Jhk99Ddo)?+ zlx%lcbahyB=(y(Bw|ouJMTbipbf=4}Lq;)XwQxE>$uqd2iLIx=gdNl4VGh z(LI0s6Vu@CEXktO3&};6I%ivX*Ga#J8dMfquMHJ8Y&9+HJn49yh#dZT?)=%C$^r%% zTdYHdx#vfBy?UzIQ8^u;*n9i2oez6ze7EJs;T&_dg~1j|1#N&SaBKCRO1*BSZywWh z=H1;ad}lLXNmpfupEzfJ?Y#Jk^__s}e`b&CgcPC-&N~ISI}L}4KMR|v^e317UCV#! z=e*%}#ilNSWbL==_VSB2LTr5n-)l%UwJ&)y#aB%+t`AQ(eRf|W8#=6TtB_&?10G)f zrOd*Q?BScLyy_o5 zMb&BhA;vXTW<9N-W-RJ?&{5>cExm}r$yGgtn|78uOSpmY3~rTs^-otsypSfz&M&$vcKFlnFMn(NBao%MZh zard*(Q|m1S#yod;V`F2TrB5mzVbr{5aVXg1$r-6u!$MKVA0zVH`ie(?XT!X>;W>dx z)yR!wo8LZ;sQI zt16viN4LKW`tEXn^Lpf(twY_DroJ;R^}J#43T%pv!UX^Emz5t^s;Y{M7`a%jT$S}8 ze$7NZL$#i|oLHNnxG98Mzv$I_-i>w4{N$V3_#0&!(!Ci}V|OO-?Z6Y+bV1~u&2;$Y>O%UxIcM>{l)U2+#)ktC9IzHN1v zm|dlzlUGo4Pmq%2xb&0`H?ObH8`}{D#dznR_Mf&i+%2m&wUt%bA^(})JZSql)bN}9 za)j5=)Qlg~h{Z;&cfoTuqf-;wGCNK@v8g$@X=n9+y7_C_+XLFvFU)l1`uFnYIOg?> zwN0S?W%r!5(xmDA z6@Q%->K4zy@0_RKJcOmkh|LB9fg6XO<-YH_&zRiwCCozbc{+ciK}WW6ueh&h0qgla zwIqp{r~EIchQtqzecZ)ub3lIV``ktDa|!Gme7W|;N@OkRy9(#_X}Aic^mk^RSKF8_ z##g-Lws~Zm3j52NABmq%?O>G8G*){fQ!pOE@!zj1u6Tv>htg{2Z{IuX^SXNNja$j} zZ9YeI3f@ocwSVyRnwn`p(~sg@C&SH2859eq;&=))|xD zTJGlPyQwA?#LSoy=`-22TX6y*85LYS9TqLGS?Jk6xV-( zE!M&+tWr+?g>Ig?d)EMzjhmD8TsDfNO%CafUc2Qfa@3}43u{9nBsg{N|IbhMGPf14 zAI4WPzY>w>O3LYRs+kR^lP{*8(Xc!%L3=%NGn84yCAmna-v1M=OEW#f;irD$&8SV> zm)2O7{2O>*+Ujo3TBNflIes*?=lpLt*xlkesomn3Nz43==WQ}u{R#hX7r0vbQlg_7 zI;Ol2u{B2K1@w!?@sG6+J5ozDuFA0IL|qkmQ!KVcVa7@M=q=`crBtQb`3ZAodBq3w z@o8_}N_;!iLhMMo%YMnrlTyQ~aKiRU*7=k= z8r#m&a=CkJwi2obPb5|`cHHQErsVIr^gBVsvt2qort#_sK}Z>#bUoSgl6ok}ry}`iW`abx z?NzT+JSS_Sd2?hQJs!1tZE`?q_L&sbwIx|G`buHQ5IuQ>Tk>_$zA#7rMeb*YYEIVqD#=ZK)&q0WdN%&V>pApzH#=G!@vUx>R*PXI+ z*->As$M`pDZR;zW()Qaq-0e^)A2AB@vr7-7v~ zf-7On?`9(sYL%;bbRzh86*y{jI5O9R-fETW&exjCZBxt}-tA`OyILck{Gqu^=0g-I zVqx^OOyH|NmSFatgDtAg@bhVsB=~ln9bdl~xbB#II6I4`j<+?bZ#M|3r?8+?K zx9v(^X|%QXKKHiM4(kT8Y97GW1fVvw11&}a2p4&v{@VehqL)C#XahCz8&J>W1MQwZ z5SEvLYD)(~{|ONFDnN~P0rHM7K&uD`x`Z!~&pZc$NgRl+`+RJTWK97Eay1Yv5w$)yqK8r(p+R}7?z0-zPw1N`d-Lh2Pz_i_T^Nd~yw z2E?EQ(A^#boO=mWy$ZZfd!Qve0Lp3?(0L+(#!d%v{d=IOUjuSn7Er>tfEZl|IwcsW zbgb)UaiDvo0HyI0KK~5RT{i)EZ32ejpFqE@3naNYAU25tWh4v;lM_IV-w4#7H-Ta1 z98ju^f%1?F43qnSYFUJ590l525ulp*0qO01ppFwjJ@5b^|20rgJ^~u&C7^L10a~~& zP;(TpM-o5@*$>oxRrneKKt0P0B*qG0`1cYh@gw-0RUnSzS*o4_wH~iGxB-Zfet`Q? zKvVq*1REBg*#M{~41w6w22{J#K)uibbcJ*v8rFeeRRx+hKh{ARsMnN$;VW(|_TL5C zo_j!5#lF1q0h&M-(4?Y)FbxFyem?-$Pe9wX2dFN;f%fz;5WfZSo)>}kg$wK22gI>n zARRBnno9%q%55MP2%r^B0BOP%s5TZr9@7NUq#;n(8i8TR6sWt$@!qxr5s(eEtL;Gf zHVMQQS0L@f{zNPRDgGi*w-f-~D-)xh zE2{v!3_$xQ4J7JWpmNFprN9(uZF4{-*nqzAGSIF`A&>KcD)bC!r%HfsrVGU6E`Zz$ zARb_kjotuNYX(TKF940B7UNX!B2F8HWfY)6x1Q5m^{>7S1cmOTqHuC)x5W9kbwuU@C_W+31=Ri}# z`^rLmJ0o6>V-2nw1MOoj5WWRKHGcubHEW<5U;|(y5V436dF;_l0ua`SbxkIqEH?u= z(Gy4_H-YwT5s1IJKeE=_}apmz%aiDh$$tY-}ndABfUWGLOewmB8DGg z?F11UW`%dLEu@ z0I2&n0^r*x()QN?>0l%f78g(hEfH^nK)ikl^k{DYbuA!%q9%mK0wH|>C{f-(d_D$r z+ao}~IRzA(1fZHe!g?V`t!05ugah^CcGQh;z%ZhWJwZKI@BrX>hJTL(${p14^iF`? zM}ZhZoEfD7bzKkO-9sRFQ5Usq(Z>+25TjZDzP+jk%?jgQ2WPxnL3sk3B zpo<#eW3z!enuC}|op#FrlFhrLy756C&x?4C zJO)J08zBEfP0ua^@=Mgd(Rv`sC;+9y8@Y59s0kj(4gB2+wY%ao!009Pn473+=n=m* z0|a>?H%{1N0_Afv+vjEy{BZbp3Gko?JqdMj3*PJcDWC>!1IoM!av!;1Sb+4#`)&`$vlyU9 zasyeY3$fS*B%fLUAt|7JZ2?l51&~f*uULKo&H6jgsx~8T&>vQ>0znV|_7Zc`g9AW)>IAgdE}->EA_o%@o3Y68Zh-9*nA z4nzS3y|*0b!4Hwk4*{alD?jQ0X*dnN;x>@BT>$b$GoX1R@074-au+f8INO7#{{DWGEUh#AbK1Kx3I058+)5x1R%sst`r+J{o z?*VwG4CJNfKo`Qi;8+94Dn*iVuhy%mDFN$7a0$63n5c>4+KZ(=6)FQ6+#2EkM=h0a7V)RE7q`JnE(* z>X{K{npi%}p?JMjF(6-d!}~Y}B*WW4IUxs>%YT68lmWDD$Saa3Vx1A760=+s`d@oK z)`188;1odEEKu{2Pa17N+nEL=`w$=*xB*oK_2>@zUTX*HoCy#@nERB(f%=;Vz41Ig zXA&sd+5pnw06i!1`Ir?n6M^X12gD9;%oc7yzNZLOHB+EwX#rs{4^&>{bI&qRDj#9S z8bA*J!ak!m-e3R*%zv~@%)B`S;K!8#`N}DvU&Q+^d?#7(0Aqn>>CD>7-}&q z7h(tdh$SLwXh3_G#QCGGKx_JpnXDgZ zQ46RqK0sE$e3C8!#F^Is;lrq^t2Z`Psh%sOqTse}plM zXaV)tf0)@&fA@bxjBfz)H66@L*#8}I0LzFEzSD@`P#}4w0=eS}&{$uiZX;e2w9(5^ zD>j(|)Yf5k@dxS*`fcK0#I6BQc##X5T0qgih57mf&{hx+-N?r`&w;9JjXH;Vesl!z7Vny6%gra8b1UT{^>d8aQ>7h7toCXM;1(IMG5I)_g)w$@6sB@mysFha` zUziK5P=lMVqsC1GC7>1OK*U`~CQy!C1WM#(oF$ksW1wGVU~YS>iCF0a%1{PCy(7>R zj^kr7S4oCrCX_+^BEPHOpkJVlXd|~hFuz<_0Fo~HmoLt7n#RB|Xb7|qKTv~p0o2~& z?2!e)fVoxs9_C~#puS`P5*_CyPCTa;`pIKSAi@@b*yavk7KAgHKak4VfSUXmwdET2 z6!|lRzBFTpvzjqLWI50dHv{FEJOEP$Vs8k@449QaqYfSo0Vu@2z8?p=d>D`?(ym* zoU2!`hTj32oyAx;e7eG=~1JXz-&W4+T_QnqJ zj$ZJU1XKqF)cA3r%-sRXS1y3oVxX&|?nn#a?2R60G>!Qiaq%8oHio&s0`JQ)7I7Dd zv(smweM63h#9|Ik#CylHJi}f*ngePC;`k@dp?WhoCkrC4I5DRUVSTVaS6}0-n2ElQ zy*uoS`i*~P^T40J_n{x-tUiwO3>ka!54AW2b7s9Fz`{|W@#0MDf%>AJWM1H$VF%<#W-Hv&5WRr}i)UM5l9StYIPpUwz5eG_`2M~_js7WP=W%THOIL}y6F{2#CuUh~l zrK85-yhTP$|G$n_nPY$c13LS6%(h2xhwvP8J@z*o`w;Dh*B-%K*MvI+I*?9a&K_$3 zV$*m0I{w`*33V9t<}l`#C@0h`%qT_J%XWL*UE%z(2{m-*5|Blg(R(RCTEM(l$_-$Q zk6Xt6nd<`msw{v(J?h>&tkGZe1H}JloYUqzQGZr23vEZ9M*(pPG2`!rbFKprjW2+9 z{Vvdq%79=m!#bD&*~sO#W z!9KIy#xtR&PWo;~BC&aKE60yRjhLKeYmF9kum-C1L^Rmk_V2>WUjNU(vp6R+DK#~U;efhJRk-%AG)M-?#qMSj03LG7@>yt5DIayP^lVkLGF==b=r z-e~}5h+W35rw8m|BmeGh1|sz5$i4xoP%h@pc(x=;jUZZgp2m;t6X0O+A7vj4&F zA%0#907-!c@Eb8YhFE<|;LZZ`UtJ-<5((!4oHHhc(dSSPMm&I=k2{mwsQ|V)IHUR_ zK5bAlmw_&;1JuWUxJPvW3KQnl7@XTAYJnVd4zZ|*e2D~7G0yeJamG$Wt+c{@Z6WRy z0KIA!ce6*(TmGdW4v^nISwJrI#>cGyNnIE9qZ4x}YI{ru5dJkl*Yrkj8$*B82MBx$ zw2!~AX85>4P26*d0yR7kcbpq>mdD@4bujOp29lEyFpOgFhfq^ihkiGUUI9DRpvTT6X@CkR?SgWHrKeg%sY2p!T z0_LEbXMu9Q0m$x{QKe&mJa7*8X3p5d8$i4F8Fk$Se^p|RLLZAm&EZ8{Te1Sh9&=Uv zJDd#?fnuG9`%TR58ZJO`p2TzDZc@n^XRY%<$fGv>$w0jj1-SPb`#g%=Fat2fbA+Yh z_n+Y0%Z%K>Y;X=|CU?vSJeV6}FQ9kg{$lhBQ2EaSN!SOoCSLCu15gjpfgpbeDhq*U zn8H1Y8P?Yo=V?=5nCQVh6rNjS9y0{aHPzT#*3FnDF&j?E;BL$S$lLva(mDVHmkPk9 ztB8vk%uR@GB{_gB%vxvBV@6Q(2k~t2_c5nips!#S7-Yv9V$K|~0;(4JA^JS&5bD_V zpSZ8Wyjz3WRTukTxf3;a3(%Swfrfipsudl5GaSHT1I}USp&9S-?EmL@0>FE`M=q@U z^(@Sdfj}Hm0m{9-$ZI7a)@6XS-wQq66+jlxZPtdql7QLT204LV9gkmA@dGH21+u0C zK(`Q3+AsqJqE7OnkF`_+;e`0Ll}EiB@0$pa?()}V$vVPvYV0y!;!ZfrepHl^l;|^k qK*U3Csp{)f>)4&T4+8lXN{hJo3X0OXf;<g?SQR%>cPTFXs z%}VGgQj+=W;W;+JQnnF)#c0}Xt#>em;Ep=h;TW_jwEn0Z*(#&iOH6i1ope-HmS7a0 z-j=8!lzKQ2_26@F`u-+Hr|VIy;*uD-VkF9F#}a z5Fi!5!Q_@0NQfUf3yQJ9k_|vE@EFaSr|@EMP%dh*Tam6R->1r zq6mrO`fKqZz4{b7U?$7hkjNQdb7;Qj>JxSgGf$6RHNXNtGitqkx-HQoIOxNKKLoD3 z0Mb3m%9Smq9j$Ck*;?i=|51?_Ja}p352S7zFYVmgy*k-I^9Z4TCHw(FFp|R%G#gEF zU$U905l}i0iLNZ|k54YNk?H?B6?|Vx`o-1HYiuf5&i1yrIx3!*D#1|%0D&XxF~7)M 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�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 z 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

    9=o=@S6W*>`s-(zXqsv0npSQxIwyF$! zAQFx+P`qqSK4xO;iprLWC9{+oqPA2~U##HA11}E7JhVIS^kzZllfhBj7z{o4)Kr3k z6A3`*1Ri|{F;X#s{=iTG_a(GnHS+veci@1*^DY8!2FT%#JSL6L2O5nmp!VOMr_skD zgilhq@g|@sE{Uf81 zPv{*IF7bzC

    Vovz`T)T`;Ya#$Z0SHa|PfeI+1{6}s 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

    =mM5&%b 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 VkO2&l#Yv$+QtYmHNi3Nj{}+t}`m6u| literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/objects/pack/pack-f72bbfa35af982c2a60735152c80b24ee981cf102db76764c383f9b87935d0d3.idx b/tests/resources/testrepo_256.git/objects/pack/pack-f72bbfa35af982c2a60735152c80b24ee981cf102db76764c383f9b87935d0d3.idx new file mode 100644 index 0000000000000000000000000000000000000000..1d197e87085e32a838da41a976b0dbf13938628b GIT binary patch literal 1336 zcmexg;-AdGz`z8=qk!}fU<7KRB?iUIKx1a08>od@fM!t>vjWW|?pt)*BaNFAyuP`%y7il{<)*l^up!FyVBLILX1~6UNj$>y7hv+?ty1Foih&9c8$9gZVTN(b|vv=+n z%vY#cef;}9o3l0T7e94ekq+)qb=qWeh$CyJ*trPpZY`#4Uej*2!>e|k<5Vsvk1x8F z`%9#=a4pwHFQtQVS#mr{Q3uw%)UbRqOEe-N)H^;`N0UujbJgVEHTHi0cWu3Y$MxLK zpUXA3KYsl0)3(#!e%|Q&dsA7I#cSe0dj`fGuHSS0ez(6`_s#Zi{DH~88P9h5PoBX8 za<(VeAqN45_n*7=abMb;A|~*W`QDLge}8v&U#5+p>zV&KtO$0Tx=zVq?E{J0XHvmM z5#?NM6N)^_4mjvcoe{j&?$m`Dv!>6vyUucog_rS`m&K6}??tAyYOlTZaEXcj`nR8E ztk~bb$0vP*UUZ3}2tRvCN80w_@TvAe#gqFFUfn%$QOBLO{Y5s*lYAdr>(2I0yPnUfJA41>o9i!$GHl)_^lURw zGqx${veU9^^TXL&loJDdfzC2AGQx0KM)i`y;->57*SAgA zJ|i7bzI2!Azy7+KBWX(y{>!QC)t>f|L13~N&sIhpE@NT{O=oZWuDyS8)X%0v%h*jt abs9GLy=*)$pu0Ui<#6-Q9hIgRE&~9e7#2MM literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/packed-refs b/tests/resources/testrepo_256.git/packed-refs new file mode 100644 index 0000000000000000000000000000000000000000..995685f0805b69e8fd59cf53bc650e686e434d2b GIT binary patch literal 204 zcmZXNI}XAy5C!|3!V)!#v-a9+ZnIy3Kq4ZMxIRfu^@HFC4x3s#y z+|u^`?8i*4g;OEaRys*ADkJtHmcy*~;?>zCJGHtrsZ;_Kvr-v^!&TCmp6`dW&F7Wd uqyhxqb-^%V7l4Lp4VFL#AeB-~sV)NsW#tM@W3T|%gN?}l$?NXhKK%d*XFh=d literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/refs/blobs/annotated_tag_to_blob b/tests/resources/testrepo_256.git/refs/blobs/annotated_tag_to_blob new file mode 100644 index 0000000000000000000000000000000000000000..2723f8909fe0432ce61043856b81d2178e2eb784 GIT binary patch literal 65 zcmV~$M*+Yv33D@dgxpO;5uC=Q4yK| literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/refs/heads/br2 b/tests/resources/testrepo_256.git/refs/heads/br2 new file mode 100644 index 0000000000000000000000000000000000000000..2abd96e09922b7dfa32d05f43ccbb653db845ffb GIT binary patch literal 65 zcmV~$!2!TP1O&i;s<9mQ$|0fu5;9YVu-QoAgaAV@Rgc~r+MH7QI(vPp8((XRIgAXk H_xke#CNvOv literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/refs/heads/cannot-fetch b/tests/resources/testrepo_256.git/refs/heads/cannot-fetch new file mode 100644 index 0000000000000000000000000000000000000000..2abd96e09922b7dfa32d05f43ccbb653db845ffb GIT binary patch literal 65 zcmV~$!2!TP1O&i;s<9mQ$|0fu5;9YVu-QoAgaAV@Rgc~r+MH7QI(vPp8((XRIgAXk H_xke#CNvOv literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/refs/heads/chomped b/tests/resources/testrepo_256.git/refs/heads/chomped new file mode 100644 index 0000000000000000000000000000000000000000..de0d95305dfbc83d1f2b376a331005890d3e09ec GIT binary patch literal 65 zcmV~$!4Uu<2m`?XRTCo$lye!N{}SA_vRmmZ+jx3dqodJ}jDjwkOH{JpdquK)93_OK Hx0`(rSb!0c literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/refs/heads/haacked b/tests/resources/testrepo_256.git/refs/heads/haacked new file mode 100644 index 0000000000000000000000000000000000000000..5feda4d4178149242b68a6409bf96f577ed6d23b GIT binary patch literal 65 zcmV~$!2!S^2m`=>r$G!L<6wmSN9bL2LP2pcW$k^3mU+o~-7ezxjyo!A!f|TBY>5yP Hp}qM1NzV~m literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/refs/heads/master b/tests/resources/testrepo_256.git/refs/heads/master new file mode 100644 index 0000000000000000000000000000000000000000..106231c4cfa19e80bb86d4e01f3c1924bc9d27ae GIT binary patch literal 65 zcmV~$!2!S^2m`=>ry&B0<4^+okKi46R literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/refs/heads/not-good b/tests/resources/testrepo_256.git/refs/heads/not-good new file mode 100644 index 0000000000000000000000000000000000000000..106231c4cfa19e80bb86d4e01f3c1924bc9d27ae GIT binary patch literal 65 zcmV~$!2!S^2m`=>ry&B0<4^+okKi46R literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/refs/heads/packed-test b/tests/resources/testrepo_256.git/refs/heads/packed-test new file mode 100644 index 0000000000000000000000000000000000000000..7c2c5e4383f559373ff5281d28e0cf892818c9a6 GIT binary patch literal 65 zcmV~$Nddqx2n4`?)j(Mw$l;2A37LT`9V9fO6Mw@kID&m;>fBi(=&qTN-qAHdQF}ry)u)jss%$AHh2VXfWL(bRD%@;nA3kSUz&wvid`9l{r=fsg#vv&CkKi4*h5AIb087(a#JsY&J2n(Njh}%!%kRLEAndYi HLR7y8IolCM literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/refs/heads/trailing b/tests/resources/testrepo_256.git/refs/heads/trailing new file mode 100644 index 0000000000000000000000000000000000000000..de0d95305dfbc83d1f2b376a331005890d3e09ec GIT binary patch literal 65 zcmV~$!4Uu<2m`?XRTCo$lye!N{}SA_vRmmZ+jx3dqodJ}jDjwkOH{JpdquK)93_OK Hx0`(rSb!0c literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/refs/heads/with-empty-log b/tests/resources/testrepo_256.git/refs/heads/with-empty-log new file mode 100644 index 0000000000000000000000000000000000000000..bd392a7d2ae81d2ff4c1cb58aeaa334bb6499bff GIT binary patch literal 65 zcmWN@Hvzyf3;?jdXuO@k@#GI7)g>P><`_(v!wTFvA%ecQwJMeP0 IYq{wA0Z)q&YXATM literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/refs/remotes/test/master b/tests/resources/testrepo_256.git/refs/remotes/test/master new file mode 100644 index 0000000000000000000000000000000000000000..ee4aa140b3354725b47ab5d5b8c8e4a799625ec0 GIT binary patch literal 65 zcmWN_!2y6U2m`>s)7TK9j6h($ literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/refs/tags/annotated_tag_to_blob b/tests/resources/testrepo_256.git/refs/tags/annotated_tag_to_blob new file mode 100644 index 0000000000000000000000000000000000000000..2723f8909fe0432ce61043856b81d2178e2eb784 GIT binary patch literal 65 zcmV~$M*+Yv33D@dgxpO;5uC=Q4yK| literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/refs/tags/e90810b b/tests/resources/testrepo_256.git/refs/tags/e90810b new file mode 100644 index 0000000000000000000000000000000000000000..eb8846a05a50211349d887f451ccae5ea9e00654 GIT binary patch literal 65 zcmWm2$q|4s3rs^2m`Ra*94pbJ_iE%|AbbXu&*;)P6&!dU=|7h`m! HmczdvNf{B} literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo_256.git/refs/tags/taggerless b/tests/resources/testrepo_256.git/refs/tags/taggerless new file mode 100644 index 0000000000000000000000000000000000000000..45547b7fa0c9cf79272822ca2f1b5eb37cd18add GIT binary patch literal 65 zcmWN;$pOGH2m`Qxrzznws^{6^)Qh<|*F}uBiS9q&uTXck%t`d3|^NbU} HO<8rs^2m`Ra*94pbJ_iE%|AbbXu&*;)P6&! +#endif + static char *path_save; void test_path__initialize(void) @@ -757,7 +761,7 @@ void test_path__validate_current_user_ownership(void) cl_git_fail(git_fs_path_owner_is_current_user(&is_cur, "c:\\path\\does\\not\\exist")); #else cl_git_pass(git_fs_path_owner_is_current_user(&is_cur, "/")); - cl_assert_equal_i(is_cur, 0); + cl_assert_equal_i(is_cur, (geteuid() == 0)); cl_git_fail(git_fs_path_owner_is_current_user(&is_cur, "/path/does/not/exist")); #endif diff --git a/tests/libgit2/network/url/joinpath.c b/tests/util/url/joinpath.c similarity index 93% rename from tests/libgit2/network/url/joinpath.c rename to tests/util/url/joinpath.c index bf4557138..9fc02cde4 100644 --- a/tests/libgit2/network/url/joinpath.c +++ b/tests/util/url/joinpath.c @@ -4,19 +4,19 @@ static git_net_url source, target; -void test_network_url_joinpath__initialize(void) +void test_url_joinpath__initialize(void) { memset(&source, 0, sizeof(source)); memset(&target, 0, sizeof(target)); } -void test_network_url_joinpath__cleanup(void) +void test_url_joinpath__cleanup(void) { git_net_url_dispose(&source); git_net_url_dispose(&target); } -void test_network_url_joinpath__target_paths_and_queries(void) +void test_url_joinpath__target_paths_and_queries(void) { cl_git_pass(git_net_url_parse(&source, "http://example.com/a/b")); @@ -31,7 +31,7 @@ void test_network_url_joinpath__target_paths_and_queries(void) git_net_url_dispose(&target); } -void test_network_url_joinpath__source_query_removed(void) +void test_url_joinpath__source_query_removed(void) { cl_git_pass(git_net_url_parse(&source, "http://example.com/a/b?query&one&two")); @@ -46,7 +46,7 @@ void test_network_url_joinpath__source_query_removed(void) git_net_url_dispose(&target); } -void test_network_url_joinpath__source_lacks_path(void) +void test_url_joinpath__source_lacks_path(void) { cl_git_pass(git_net_url_parse(&source, "http://example.com")); @@ -91,7 +91,7 @@ void test_network_url_joinpath__source_lacks_path(void) git_net_url_dispose(&target); } -void test_network_url_joinpath__source_is_slash(void) +void test_url_joinpath__source_is_slash(void) { cl_git_pass(git_net_url_parse(&source, "http://example.com/")); @@ -137,7 +137,7 @@ void test_network_url_joinpath__source_is_slash(void) } -void test_network_url_joinpath__source_has_query(void) +void test_url_joinpath__source_has_query(void) { cl_git_pass(git_net_url_parse(&source, "http://example.com?query")); @@ -183,7 +183,7 @@ void test_network_url_joinpath__source_has_query(void) } -void test_network_url_joinpath__empty_query_ignored(void) +void test_url_joinpath__empty_query_ignored(void) { cl_git_pass(git_net_url_parse(&source, "http://example.com/foo")); diff --git a/tests/libgit2/network/url/parse.c b/tests/util/url/parse.c similarity index 64% rename from tests/libgit2/network/url/parse.c rename to tests/util/url/parse.c index 8149ba52c..631d9b456 100644 --- a/tests/libgit2/network/url/parse.c +++ b/tests/util/url/parse.c @@ -3,19 +3,19 @@ static git_net_url conndata; -void test_network_url_parse__initialize(void) +void test_url_parse__initialize(void) { memset(&conndata, 0, sizeof(conndata)); } -void test_network_url_parse__cleanup(void) +void test_url_parse__cleanup(void) { git_net_url_dispose(&conndata); } /* Hostname */ -void test_network_url_parse__hostname_trivial(void) +void test_url_parse__hostname_trivial(void) { cl_git_pass(git_net_url_parse(&conndata, "http://example.com/resource")); cl_assert_equal_s(conndata.scheme, "http"); @@ -24,10 +24,12 @@ void test_network_url_parse__hostname_trivial(void) cl_assert_equal_s(conndata.path, "/resource"); cl_assert_equal_p(conndata.username, NULL); cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_p(conndata.query, NULL); + cl_assert_equal_p(conndata.fragment, NULL); cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_parse__hostname_root(void) +void test_url_parse__hostname_root(void) { cl_git_pass(git_net_url_parse(&conndata, "http://example.com/")); cl_assert_equal_s(conndata.scheme, "http"); @@ -36,10 +38,12 @@ void test_network_url_parse__hostname_root(void) cl_assert_equal_s(conndata.path, "/"); cl_assert_equal_p(conndata.username, NULL); cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_p(conndata.query, NULL); + cl_assert_equal_p(conndata.fragment, NULL); cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_parse__hostname_implied_root(void) +void test_url_parse__hostname_implied_root(void) { cl_git_pass(git_net_url_parse(&conndata, "http://example.com")); cl_assert_equal_s(conndata.scheme, "http"); @@ -48,10 +52,26 @@ void test_network_url_parse__hostname_implied_root(void) cl_assert_equal_s(conndata.path, "/"); cl_assert_equal_p(conndata.username, NULL); cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_p(conndata.query, NULL); + cl_assert_equal_p(conndata.fragment, NULL); cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_parse__hostname_implied_root_custom_port(void) +void test_url_parse__hostname_numeric(void) +{ + cl_git_pass(git_net_url_parse(&conndata, "http://8888888/")); + cl_assert_equal_s(conndata.scheme, "http"); + cl_assert_equal_s(conndata.host, "8888888"); + cl_assert_equal_s(conndata.port, "80"); + cl_assert_equal_s(conndata.path, "/"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_p(conndata.query, NULL); + cl_assert_equal_p(conndata.fragment, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); +} + +void test_url_parse__hostname_implied_root_custom_port(void) { cl_git_pass(git_net_url_parse(&conndata, "http://example.com:42")); cl_assert_equal_s(conndata.scheme, "http"); @@ -60,10 +80,12 @@ void test_network_url_parse__hostname_implied_root_custom_port(void) cl_assert_equal_s(conndata.path, "/"); cl_assert_equal_p(conndata.username, NULL); cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_p(conndata.query, NULL); + cl_assert_equal_p(conndata.fragment, NULL); cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_url_parse__hostname_implied_root_empty_port(void) +void test_url_parse__hostname_implied_root_empty_port(void) { cl_git_pass(git_net_url_parse(&conndata, "http://example.com:")); cl_assert_equal_s(conndata.scheme, "http"); @@ -72,10 +94,12 @@ void test_network_url_parse__hostname_implied_root_empty_port(void) cl_assert_equal_s(conndata.path, "/"); cl_assert_equal_p(conndata.username, NULL); cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_p(conndata.query, NULL); + cl_assert_equal_p(conndata.fragment, NULL); cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_parse__hostname_encoded_password(void) +void test_url_parse__hostname_encoded_password(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user:pass%2fis%40bad@hostname.com:1234/")); @@ -85,10 +109,12 @@ void test_network_url_parse__hostname_encoded_password(void) cl_assert_equal_s(conndata.path, "/"); cl_assert_equal_s(conndata.username, "user"); cl_assert_equal_s(conndata.password, "pass/is@bad"); + cl_assert_equal_p(conndata.query, NULL); + cl_assert_equal_p(conndata.fragment, NULL); cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_url_parse__hostname_user(void) +void test_url_parse__hostname_user(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user@example.com/resource")); @@ -98,10 +124,12 @@ void test_network_url_parse__hostname_user(void) cl_assert_equal_s(conndata.path, "/resource"); cl_assert_equal_s(conndata.username, "user"); cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_p(conndata.query, NULL); + cl_assert_equal_p(conndata.fragment, NULL); cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_parse__hostname_user_pass(void) +void test_url_parse__hostname_user_pass(void) { /* user:pass@hostname.tld/resource */ cl_git_pass(git_net_url_parse(&conndata, @@ -112,10 +140,12 @@ void test_network_url_parse__hostname_user_pass(void) cl_assert_equal_s(conndata.path, "/resource"); cl_assert_equal_s(conndata.username, "user"); cl_assert_equal_s(conndata.password, "pass"); + cl_assert_equal_p(conndata.query, NULL); + cl_assert_equal_p(conndata.fragment, NULL); cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_parse__hostname_port(void) +void test_url_parse__hostname_port(void) { /* hostname.tld:port/resource */ cl_git_pass(git_net_url_parse(&conndata, @@ -126,10 +156,12 @@ void test_network_url_parse__hostname_port(void) cl_assert_equal_s(conndata.path, "/resource"); cl_assert_equal_p(conndata.username, NULL); cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_p(conndata.query, NULL); + cl_assert_equal_p(conndata.fragment, NULL); cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_url_parse__hostname_empty_port(void) +void test_url_parse__hostname_empty_port(void) { cl_git_pass(git_net_url_parse(&conndata, "http://example.com:/resource")); cl_assert_equal_s(conndata.scheme, "http"); @@ -138,10 +170,12 @@ void test_network_url_parse__hostname_empty_port(void) cl_assert_equal_s(conndata.path, "/resource"); cl_assert_equal_p(conndata.username, NULL); cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_p(conndata.query, NULL); + cl_assert_equal_p(conndata.fragment, NULL); cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_parse__hostname_user_port(void) +void test_url_parse__hostname_user_port(void) { /* user@hostname.tld:port/resource */ cl_git_pass(git_net_url_parse(&conndata, @@ -152,10 +186,12 @@ void test_network_url_parse__hostname_user_port(void) cl_assert_equal_s(conndata.path, "/resource"); cl_assert_equal_s(conndata.username, "user"); cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_p(conndata.query, NULL); + cl_assert_equal_p(conndata.fragment, NULL); cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_url_parse__hostname_user_pass_port(void) +void test_url_parse__hostname_user_pass_port(void) { /* user:pass@hostname.tld:port/resource */ cl_git_pass(git_net_url_parse(&conndata, @@ -166,12 +202,78 @@ void test_network_url_parse__hostname_user_pass_port(void) cl_assert_equal_s(conndata.path, "/resource"); cl_assert_equal_s(conndata.username, "user"); cl_assert_equal_s(conndata.password, "pass"); + cl_assert_equal_p(conndata.query, NULL); + cl_assert_equal_p(conndata.fragment, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); +} + +void test_url_parse__hostname_user_pass_port_query(void) +{ + /* user:pass@hostname.tld:port/resource */ + cl_git_pass(git_net_url_parse(&conndata, + "https://user:pass@example.com:9191/resource?query=q&foo=bar&z=asdf")); + cl_assert_equal_s(conndata.scheme, "https"); + cl_assert_equal_s(conndata.host, "example.com"); + cl_assert_equal_s(conndata.port, "9191"); + cl_assert_equal_s(conndata.path, "/resource"); + cl_assert_equal_s(conndata.username, "user"); + cl_assert_equal_s(conndata.password, "pass"); + cl_assert_equal_s(conndata.query, "query=q&foo=bar&z=asdf"); + cl_assert_equal_p(conndata.fragment, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); +} + +void test_url_parse__hostname_user_pass_port_fragment(void) +{ + /* user:pass@hostname.tld:port/resource */ + cl_git_pass(git_net_url_parse(&conndata, + "https://user:pass@example.com:9191/resource#fragment")); + cl_assert_equal_s(conndata.scheme, "https"); + cl_assert_equal_s(conndata.host, "example.com"); + cl_assert_equal_s(conndata.port, "9191"); + cl_assert_equal_s(conndata.path, "/resource"); + cl_assert_equal_s(conndata.username, "user"); + cl_assert_equal_s(conndata.password, "pass"); + cl_assert_equal_p(conndata.query, NULL); + cl_assert_equal_s(conndata.fragment, "fragment"); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); +} + +void test_url_parse__hostname_user_pass_port_query_fragment(void) +{ + /* user:pass@hostname.tld:port/resource */ + cl_git_pass(git_net_url_parse(&conndata, + "https://user:pass@example.com:9191/resource?query=q&foo=bar&z=asdf#fragment")); + cl_assert_equal_s(conndata.scheme, "https"); + cl_assert_equal_s(conndata.host, "example.com"); + cl_assert_equal_s(conndata.port, "9191"); + cl_assert_equal_s(conndata.path, "/resource"); + cl_assert_equal_s(conndata.username, "user"); + cl_assert_equal_s(conndata.password, "pass"); + cl_assert_equal_s(conndata.query, "query=q&foo=bar&z=asdf"); + cl_assert_equal_s(conndata.fragment, "fragment"); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); +} + +void test_url_parse__fragment_with_question_mark(void) +{ + /* user:pass@hostname.tld:port/resource */ + cl_git_pass(git_net_url_parse(&conndata, + "https://user:pass@example.com:9191/resource#fragment_with?question_mark")); + cl_assert_equal_s(conndata.scheme, "https"); + cl_assert_equal_s(conndata.host, "example.com"); + cl_assert_equal_s(conndata.port, "9191"); + cl_assert_equal_s(conndata.path, "/resource"); + cl_assert_equal_s(conndata.username, "user"); + cl_assert_equal_s(conndata.password, "pass"); + cl_assert_equal_p(conndata.query, NULL); + cl_assert_equal_s(conndata.fragment, "fragment_with?question_mark"); cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } /* IPv4 addresses */ -void test_network_url_parse__ipv4_trivial(void) +void test_url_parse__ipv4_trivial(void) { cl_git_pass(git_net_url_parse(&conndata, "http://192.168.1.1/resource")); cl_assert_equal_s(conndata.scheme, "http"); @@ -183,7 +285,7 @@ void test_network_url_parse__ipv4_trivial(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_parse__ipv4_root(void) +void test_url_parse__ipv4_root(void) { cl_git_pass(git_net_url_parse(&conndata, "http://192.168.1.1/")); cl_assert_equal_s(conndata.scheme, "http"); @@ -195,7 +297,7 @@ void test_network_url_parse__ipv4_root(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_parse__ipv4_implied_root(void) +void test_url_parse__ipv4_implied_root(void) { cl_git_pass(git_net_url_parse(&conndata, "http://192.168.1.1")); cl_assert_equal_s(conndata.scheme, "http"); @@ -207,7 +309,7 @@ void test_network_url_parse__ipv4_implied_root(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_parse__ipv4_implied_root_custom_port(void) +void test_url_parse__ipv4_implied_root_custom_port(void) { cl_git_pass(git_net_url_parse(&conndata, "http://192.168.1.1:42")); cl_assert_equal_s(conndata.scheme, "http"); @@ -219,7 +321,7 @@ void test_network_url_parse__ipv4_implied_root_custom_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_url_parse__ipv4_implied_root_empty_port(void) +void test_url_parse__ipv4_implied_root_empty_port(void) { cl_git_pass(git_net_url_parse(&conndata, "http://192.168.1.1:")); cl_assert_equal_s(conndata.scheme, "http"); @@ -231,7 +333,7 @@ void test_network_url_parse__ipv4_implied_root_empty_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_parse__ipv4_encoded_password(void) +void test_url_parse__ipv4_encoded_password(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user:pass%2fis%40bad@192.168.1.1:1234/")); @@ -244,7 +346,7 @@ void test_network_url_parse__ipv4_encoded_password(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_url_parse__ipv4_user(void) +void test_url_parse__ipv4_user(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user@192.168.1.1/resource")); @@ -257,7 +359,7 @@ void test_network_url_parse__ipv4_user(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_parse__ipv4_user_pass(void) +void test_url_parse__ipv4_user_pass(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user:pass@192.168.1.1/resource")); @@ -270,7 +372,7 @@ void test_network_url_parse__ipv4_user_pass(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_parse__ipv4_port(void) +void test_url_parse__ipv4_port(void) { cl_git_pass(git_net_url_parse(&conndata, "https://192.168.1.1:9191/resource")); @@ -283,7 +385,7 @@ void test_network_url_parse__ipv4_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_url_parse__ipv4_empty_port(void) +void test_url_parse__ipv4_empty_port(void) { cl_git_pass(git_net_url_parse(&conndata, "http://192.168.1.1:/resource")); cl_assert_equal_s(conndata.scheme, "http"); @@ -295,7 +397,7 @@ void test_network_url_parse__ipv4_empty_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_parse__ipv4_user_port(void) +void test_url_parse__ipv4_user_port(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user@192.168.1.1:9191/resource")); @@ -308,7 +410,7 @@ void test_network_url_parse__ipv4_user_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_url_parse__ipv4_user_pass_port(void) +void test_url_parse__ipv4_user_pass_port(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user:pass@192.168.1.1:9191/resource")); @@ -323,7 +425,7 @@ void test_network_url_parse__ipv4_user_pass_port(void) /* IPv6 addresses */ -void test_network_url_parse__ipv6_trivial(void) +void test_url_parse__ipv6_trivial(void) { cl_git_pass(git_net_url_parse(&conndata, "http://[fe80::dcad:beff:fe00:0001]/resource")); cl_assert_equal_s(conndata.scheme, "http"); @@ -335,7 +437,7 @@ void test_network_url_parse__ipv6_trivial(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_parse__ipv6_root(void) +void test_url_parse__ipv6_root(void) { cl_git_pass(git_net_url_parse(&conndata, "http://[fe80::dcad:beff:fe00:0001]/")); cl_assert_equal_s(conndata.scheme, "http"); @@ -347,7 +449,7 @@ void test_network_url_parse__ipv6_root(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_parse__ipv6_implied_root(void) +void test_url_parse__ipv6_implied_root(void) { cl_git_pass(git_net_url_parse(&conndata, "http://[fe80::dcad:beff:fe00:0001]")); cl_assert_equal_s(conndata.scheme, "http"); @@ -359,7 +461,7 @@ void test_network_url_parse__ipv6_implied_root(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_parse__ipv6_implied_root_custom_port(void) +void test_url_parse__ipv6_implied_root_custom_port(void) { cl_git_pass(git_net_url_parse(&conndata, "http://[fe80::dcad:beff:fe00:0001]:42")); cl_assert_equal_s(conndata.scheme, "http"); @@ -371,7 +473,7 @@ void test_network_url_parse__ipv6_implied_root_custom_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_url_parse__ipv6_implied_root_empty_port(void) +void test_url_parse__ipv6_implied_root_empty_port(void) { cl_git_pass(git_net_url_parse(&conndata, "http://[fe80::dcad:beff:fe00:0001]:")); cl_assert_equal_s(conndata.scheme, "http"); @@ -383,7 +485,7 @@ void test_network_url_parse__ipv6_implied_root_empty_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_parse__ipv6_encoded_password(void) +void test_url_parse__ipv6_encoded_password(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user:pass%2fis%40bad@[fe80::dcad:beff:fe00:0001]:1234/")); @@ -396,7 +498,7 @@ void test_network_url_parse__ipv6_encoded_password(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_url_parse__ipv6_user(void) +void test_url_parse__ipv6_user(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user@[fe80::dcad:beff:fe00:0001]/resource")); @@ -409,7 +511,7 @@ void test_network_url_parse__ipv6_user(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_parse__ipv6_user_pass(void) +void test_url_parse__ipv6_user_pass(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user:pass@[fe80::dcad:beff:fe00:0001]/resource")); @@ -422,7 +524,7 @@ void test_network_url_parse__ipv6_user_pass(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_parse__ipv6_port(void) +void test_url_parse__ipv6_port(void) { cl_git_pass(git_net_url_parse(&conndata, "https://[fe80::dcad:beff:fe00:0001]:9191/resource")); @@ -435,7 +537,7 @@ void test_network_url_parse__ipv6_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_url_parse__ipv6_empty_port(void) +void test_url_parse__ipv6_empty_port(void) { cl_git_pass(git_net_url_parse(&conndata, "http://[fe80::dcad:beff:fe00:0001]:/resource")); cl_assert_equal_s(conndata.scheme, "http"); @@ -447,7 +549,7 @@ void test_network_url_parse__ipv6_empty_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_parse__ipv6_user_port(void) +void test_url_parse__ipv6_user_port(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user@[fe80::dcad:beff:fe00:0001]:9191/resource")); @@ -460,7 +562,7 @@ void test_network_url_parse__ipv6_user_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_url_parse__ipv6_user_pass_port(void) +void test_url_parse__ipv6_user_pass_port(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user:pass@[fe80::dcad:beff:fe00:0001]:9191/resource")); @@ -473,7 +575,7 @@ void test_network_url_parse__ipv6_user_pass_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_url_parse__ipv6_invalid_addresses(void) +void test_url_parse__ipv6_invalid_addresses(void) { /* Opening bracket missing */ cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, @@ -526,6 +628,7 @@ void test_network_url_parse__ipv6_invalid_addresses(void) "https://user@[fe80::dcad:beff:fe00:0001:9191/resource")); cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, "https://user:pass@[fe80::dcad:beff:fe00:0001:9191/resource")); + /* Both brackets missing */ cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, "http://fe80::dcad:beff:fe00:0001/resource")); @@ -554,4 +657,135 @@ void test_network_url_parse__ipv6_invalid_addresses(void) /* Invalid character inside address */ cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, "http://[fe8o::dcad:beff:fe00:0001]/resource")); + + /* Characters before/after braces */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://fe80::[dcad:beff:fe00:0001]/resource")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://cafe[fe80::dcad:beff:fe00:0001]/resource")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://[fe80::dcad:beff:fe00:0001]cafe/resource")); +} + +/* Oddities */ + +void test_url_parse__invalid_scheme_is_relative(void) +{ + cl_git_pass(git_net_url_parse(&conndata, "foo!bar://host:42/path/to/project?query_string=yes")); + cl_assert_equal_p(conndata.scheme, NULL); + cl_assert_equal_p(conndata.host, NULL); + cl_assert_equal_p(conndata.port, NULL); + cl_assert_equal_s(conndata.path, "foo!bar://host:42/path/to/project"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_s(conndata.query, "query_string=yes"); + cl_assert_equal_p(conndata.fragment, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); +} + +void test_url_parse__scheme_case_is_normalized(void) +{ + cl_git_pass(git_net_url_parse(&conndata, "GIT+SSH://host:42/path/to/project")); + cl_assert_equal_s(conndata.scheme, "git+ssh"); +} + +void test_url_parse__nonhierarchical_scheme(void) +{ + cl_git_pass(git_net_url_parse(&conndata, "mailto:foobar@example.com")); + cl_assert_equal_s(conndata.scheme, "mailto"); + cl_assert_equal_p(conndata.host, NULL); + cl_assert_equal_p(conndata.port, NULL); + cl_assert_equal_s(conndata.path, "foobar@example.com"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); +} + +void test_url_parse__no_scheme_relative_path(void) +{ + cl_git_pass(git_net_url_parse(&conndata, "path")); + cl_assert_equal_p(conndata.scheme, NULL); + cl_assert_equal_p(conndata.host, NULL); + cl_assert_equal_p(conndata.port, NULL); + cl_assert_equal_s(conndata.path, "path"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); +} + +void test_url_parse__no_scheme_absolute_path(void) +{ + cl_git_pass(git_net_url_parse(&conndata, "/path")); + cl_assert_equal_p(conndata.scheme, NULL); + cl_assert_equal_p(conndata.host, NULL); + cl_assert_equal_p(conndata.port, NULL); + cl_assert_equal_s(conndata.path, "/path"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); +} + +void test_url_parse__empty_path(void) +{ + cl_git_pass(git_net_url_parse(&conndata, "mailto:")); + cl_assert_equal_s(conndata.scheme, "mailto"); + cl_assert_equal_p(conndata.host, NULL); + cl_assert_equal_p(conndata.port, NULL); + cl_assert_equal_s(conndata.path, NULL); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); +} + +void test_url_parse__empty_path_with_empty_authority(void) +{ + cl_git_pass(git_net_url_parse(&conndata, "http://")); + cl_assert_equal_s(conndata.scheme, "http"); + cl_assert_equal_p(conndata.host, NULL); + cl_assert_equal_s(conndata.port, "80"); + cl_assert_equal_s(conndata.path, "/"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); +} + +void test_url_parse__http_follows_the_rfc(void) +{ + cl_git_fail(git_net_url_parse(&conndata, "https://my.email.address@gmail.com@source.developers.google.com:4433/p/my-project/r/my-repository")); +} + +void test_url_parse__ssh_from_terrible_google_rfc_violating_products(void) +{ + cl_git_pass(git_net_url_parse(&conndata, "ssh://my.email.address@gmail.com@source.developers.google.com:2022/p/my-project/r/my-repository")); + cl_assert_equal_s(conndata.scheme, "ssh"); + cl_assert_equal_s(conndata.host, "source.developers.google.com"); + cl_assert_equal_s(conndata.port, "2022"); + cl_assert_equal_s(conndata.path, "/p/my-project/r/my-repository"); + cl_assert_equal_s(conndata.username, "my.email.address@gmail.com"); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); +} + +void test_url_parse__ssh_with_password_from_terrible_google_rfc_violating_products(void) +{ + cl_git_pass(git_net_url_parse(&conndata, "ssh://my.email.address@gmail.com:seekret@source.developers.google.com:2022/p/my-project/r/my-repository")); + cl_assert_equal_s(conndata.scheme, "ssh"); + cl_assert_equal_s(conndata.host, "source.developers.google.com"); + cl_assert_equal_s(conndata.port, "2022"); + cl_assert_equal_s(conndata.path, "/p/my-project/r/my-repository"); + cl_assert_equal_s(conndata.username, "my.email.address@gmail.com"); + cl_assert_equal_s(conndata.password, "seekret"); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); +} + +void test_url_parse__spaces_in_the_name(void) +{ + cl_git_pass(git_net_url_parse(&conndata, "https://libgit2@dev.azure.com/libgit2/test/_git/spaces%20in%20the%20name")); + cl_assert_equal_s(conndata.scheme, "https"); + cl_assert_equal_s(conndata.host, "dev.azure.com"); + cl_assert_equal_s(conndata.port, "443"); + cl_assert_equal_s(conndata.path, "/libgit2/test/_git/spaces%20in%20the%20name"); + cl_assert_equal_s(conndata.username, "libgit2"); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } diff --git a/tests/libgit2/network/url/pattern.c b/tests/util/url/pattern.c similarity index 97% rename from tests/libgit2/network/url/pattern.c rename to tests/util/url/pattern.c index 5e4495f70..f183d7f5f 100644 --- a/tests/libgit2/network/url/pattern.c +++ b/tests/util/url/pattern.c @@ -7,7 +7,7 @@ struct url_pattern { bool matches; }; -void test_network_url_pattern__single(void) +void test_url_pattern__single(void) { git_net_url url; size_t i; @@ -53,7 +53,7 @@ void test_network_url_pattern__single(void) } } -void test_network_url_pattern__list(void) +void test_url_pattern__list(void) { git_net_url url; size_t i; diff --git a/tests/libgit2/network/url/redirect.c b/tests/util/url/redirect.c similarity index 84% rename from tests/libgit2/network/url/redirect.c rename to tests/util/url/redirect.c index a94db7daf..540177861 100644 --- a/tests/libgit2/network/url/redirect.c +++ b/tests/util/url/redirect.c @@ -4,17 +4,17 @@ static git_net_url conndata; -void test_network_url_redirect__initialize(void) +void test_url_redirect__initialize(void) { memset(&conndata, 0, sizeof(conndata)); } -void test_network_url_redirect__cleanup(void) +void test_url_redirect__cleanup(void) { git_net_url_dispose(&conndata); } -void test_network_url_redirect__redirect_http(void) +void test_url_redirect__redirect_http(void) { cl_git_pass(git_net_url_parse(&conndata, "http://example.com/foo/bar/baz")); @@ -28,7 +28,7 @@ void test_network_url_redirect__redirect_http(void) cl_assert_equal_p(conndata.password, NULL); } -void test_network_url_redirect__redirect_ssl(void) +void test_url_redirect__redirect_ssl(void) { cl_git_pass(git_net_url_parse(&conndata, "https://example.com/foo/bar/baz")); @@ -42,7 +42,7 @@ void test_network_url_redirect__redirect_ssl(void) cl_assert_equal_p(conndata.password, NULL); } -void test_network_url_redirect__redirect_leaves_root_path(void) +void test_url_redirect__redirect_leaves_root_path(void) { cl_git_pass(git_net_url_parse(&conndata, "https://example.com/foo/bar/baz")); @@ -56,7 +56,7 @@ void test_network_url_redirect__redirect_leaves_root_path(void) cl_assert_equal_p(conndata.password, NULL); } -void test_network_url_redirect__redirect_encoded_username_password(void) +void test_url_redirect__redirect_encoded_username_password(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user%2fname:pass%40word%zyx%v@example.com/foo/bar/baz")); @@ -70,7 +70,7 @@ void test_network_url_redirect__redirect_encoded_username_password(void) cl_assert_equal_s(conndata.password, "pass@word%zyx%v"); } -void test_network_url_redirect__redirect_cross_host_allowed(void) +void test_url_redirect__redirect_cross_host_allowed(void) { cl_git_pass(git_net_url_parse(&conndata, "https://bar.com/bar/baz")); @@ -84,7 +84,7 @@ void test_network_url_redirect__redirect_cross_host_allowed(void) cl_assert_equal_p(conndata.password, NULL); } -void test_network_url_redirect__redirect_cross_host_denied(void) +void test_url_redirect__redirect_cross_host_denied(void) { cl_git_pass(git_net_url_parse(&conndata, "https://bar.com/bar/baz")); @@ -92,7 +92,7 @@ void test_network_url_redirect__redirect_cross_host_denied(void) "https://foo.com/bar/baz", false, NULL), -1); } -void test_network_url_redirect__redirect_http_downgrade_denied(void) +void test_url_redirect__redirect_http_downgrade_denied(void) { cl_git_pass(git_net_url_parse(&conndata, "https://foo.com/bar/baz")); @@ -100,7 +100,7 @@ void test_network_url_redirect__redirect_http_downgrade_denied(void) "http://foo.com/bar/baz", true, NULL), -1); } -void test_network_url_redirect__redirect_relative(void) +void test_url_redirect__redirect_relative(void) { cl_git_pass(git_net_url_parse(&conndata, "http://foo.com/bar/baz/biff")); @@ -114,7 +114,7 @@ void test_network_url_redirect__redirect_relative(void) cl_assert_equal_p(conndata.password, NULL); } -void test_network_url_redirect__redirect_relative_ssl(void) +void test_url_redirect__redirect_relative_ssl(void) { cl_git_pass(git_net_url_parse(&conndata, "https://foo.com/bar/baz/biff")); @@ -128,7 +128,7 @@ void test_network_url_redirect__redirect_relative_ssl(void) cl_assert_equal_p(conndata.password, NULL); } -void test_network_url_redirect__service_query_no_query_params_in_location(void) +void test_url_redirect__service_query_no_query_params_in_location(void) { cl_git_pass(git_net_url_parse(&conndata, "https://foo.com/bar/info/refs?service=git-upload-pack")); @@ -137,7 +137,7 @@ void test_network_url_redirect__service_query_no_query_params_in_location(void) cl_assert_equal_s(conndata.path, "/baz"); } -void test_network_url_redirect__service_query_with_query_params_in_location(void) +void test_url_redirect__service_query_with_query_params_in_location(void) { cl_git_pass(git_net_url_parse(&conndata, "https://foo.com/bar/info/refs?service=git-upload-pack")); diff --git a/tests/libgit2/network/url/scp.c b/tests/util/url/scp.c similarity index 89% rename from tests/libgit2/network/url/scp.c rename to tests/util/url/scp.c index 8cdc832ae..0e0dce17e 100644 --- a/tests/libgit2/network/url/scp.c +++ b/tests/util/url/scp.c @@ -3,19 +3,19 @@ static git_net_url conndata; -void test_network_url_scp__initialize(void) +void test_url_scp__initialize(void) { memset(&conndata, 0, sizeof(conndata)); } -void test_network_url_scp__cleanup(void) +void test_url_scp__cleanup(void) { git_net_url_dispose(&conndata); } /* Hostname */ -void test_network_url_scp__hostname_trivial(void) +void test_url_scp__hostname_trivial(void) { cl_git_pass(git_net_url_parse_scp(&conndata, "example.com:/resource")); cl_assert_equal_s(conndata.scheme, "ssh"); @@ -27,7 +27,7 @@ void test_network_url_scp__hostname_trivial(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_scp__hostname_bracketed(void) +void test_url_scp__hostname_bracketed(void) { cl_git_pass(git_net_url_parse_scp(&conndata, "[example.com]:/resource")); cl_assert_equal_s(conndata.scheme, "ssh"); @@ -39,7 +39,7 @@ void test_network_url_scp__hostname_bracketed(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_scp__hostname_root(void) +void test_url_scp__hostname_root(void) { cl_git_pass(git_net_url_parse_scp(&conndata, "example.com:/")); cl_assert_equal_s(conndata.scheme, "ssh"); @@ -51,7 +51,7 @@ void test_network_url_scp__hostname_root(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_scp__hostname_user(void) +void test_url_scp__hostname_user(void) { cl_git_pass(git_net_url_parse_scp(&conndata, "git@example.com:/resource")); cl_assert_equal_s(conndata.scheme, "ssh"); @@ -63,7 +63,7 @@ void test_network_url_scp__hostname_user(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_scp__hostname_user_bracketed(void) +void test_url_scp__hostname_user_bracketed(void) { cl_git_pass(git_net_url_parse_scp(&conndata, "[git@example.com]:/resource")); cl_assert_equal_s(conndata.scheme, "ssh"); @@ -75,7 +75,7 @@ void test_network_url_scp__hostname_user_bracketed(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_scp__hostname_port(void) +void test_url_scp__hostname_port(void) { cl_git_pass(git_net_url_parse_scp(&conndata, "[example.com:42]:/resource")); cl_assert_equal_s(conndata.scheme, "ssh"); @@ -87,7 +87,7 @@ void test_network_url_scp__hostname_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_url_scp__hostname_user_port(void) +void test_url_scp__hostname_user_port(void) { cl_git_pass(git_net_url_parse_scp(&conndata, "[git@example.com:42]:/resource")); cl_assert_equal_s(conndata.scheme, "ssh"); @@ -99,7 +99,7 @@ void test_network_url_scp__hostname_user_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_url_scp__ipv4_trivial(void) +void test_url_scp__ipv4_trivial(void) { cl_git_pass(git_net_url_parse_scp(&conndata, "192.168.99.88:/resource/a/b/c")); cl_assert_equal_s(conndata.scheme, "ssh"); @@ -111,7 +111,7 @@ void test_network_url_scp__ipv4_trivial(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_scp__ipv4_bracketed(void) +void test_url_scp__ipv4_bracketed(void) { cl_git_pass(git_net_url_parse_scp(&conndata, "[192.168.99.88]:/resource/a/b/c")); cl_assert_equal_s(conndata.scheme, "ssh"); @@ -123,7 +123,7 @@ void test_network_url_scp__ipv4_bracketed(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_scp__ipv4_user(void) +void test_url_scp__ipv4_user(void) { cl_git_pass(git_net_url_parse_scp(&conndata, "git@192.168.99.88:/resource/a/b/c")); cl_assert_equal_s(conndata.scheme, "ssh"); @@ -135,7 +135,7 @@ void test_network_url_scp__ipv4_user(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_scp__ipv4_port(void) +void test_url_scp__ipv4_port(void) { cl_git_pass(git_net_url_parse_scp(&conndata, "[192.168.99.88:1111]:/resource/a/b/c")); cl_assert_equal_s(conndata.scheme, "ssh"); @@ -147,7 +147,7 @@ void test_network_url_scp__ipv4_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_url_scp__ipv4_user_port(void) +void test_url_scp__ipv4_user_port(void) { cl_git_pass(git_net_url_parse_scp(&conndata, "[git@192.168.99.88:1111]:/resource/a/b/c")); cl_assert_equal_s(conndata.scheme, "ssh"); @@ -159,7 +159,7 @@ void test_network_url_scp__ipv4_user_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_url_scp__ipv6_trivial(void) +void test_url_scp__ipv6_trivial(void) { cl_git_pass(git_net_url_parse_scp(&conndata, "[fe80::dcad:beff:fe00:0001]:/resource/foo")); cl_assert_equal_s(conndata.scheme, "ssh"); @@ -171,7 +171,7 @@ void test_network_url_scp__ipv6_trivial(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_scp__ipv6_user(void) +void test_url_scp__ipv6_user(void) { cl_git_pass(git_net_url_parse_scp(&conndata, "git@[fe80::dcad:beff:fe00:0001]:/resource/foo")); cl_assert_equal_s(conndata.scheme, "ssh"); @@ -183,7 +183,7 @@ void test_network_url_scp__ipv6_user(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_scp__ipv6_port(void) +void test_url_scp__ipv6_port(void) { cl_git_pass(git_net_url_parse_scp(&conndata, "[[fe80::dcad:beff:fe00:0001]:99]:/resource/foo")); cl_assert_equal_s(conndata.scheme, "ssh"); @@ -195,7 +195,7 @@ void test_network_url_scp__ipv6_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_url_scp__ipv6_user_port(void) +void test_url_scp__ipv6_user_port(void) { cl_git_pass(git_net_url_parse_scp(&conndata, "[git@[fe80::dcad:beff:fe00:0001]:99]:/resource/foo")); cl_assert_equal_s(conndata.scheme, "ssh"); @@ -207,7 +207,7 @@ void test_network_url_scp__ipv6_user_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_url_scp__hexhost_and_port(void) +void test_url_scp__hexhost_and_port(void) { cl_git_pass(git_net_url_parse_scp(&conndata, "[fe:22]:/resource/foo")); cl_assert_equal_s(conndata.scheme, "ssh"); @@ -219,7 +219,7 @@ void test_network_url_scp__hexhost_and_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_scp__malformed_ipv6_one(void) +void test_url_scp__malformed_ipv6_one(void) { cl_git_pass(git_net_url_parse_scp(&conndata, "fe80::dcad:beff:fe00:0001]:/resource")); cl_assert_equal_s(conndata.scheme, "ssh"); @@ -231,7 +231,7 @@ void test_network_url_scp__malformed_ipv6_one(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_scp__malformed_ipv6_two(void) +void test_url_scp__malformed_ipv6_two(void) { cl_git_pass(git_net_url_parse_scp(&conndata, "[fe80::dcad:beff:fe00:0001]:42]:/resource")); cl_assert_equal_s(conndata.scheme, "ssh"); @@ -243,7 +243,7 @@ void test_network_url_scp__malformed_ipv6_two(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_scp__malformed_ipv6_with_user(void) +void test_url_scp__malformed_ipv6_with_user(void) { cl_git_pass(git_net_url_parse_scp(&conndata, "git@[fe80::dcad:beff:fe00:0001]:42]:/resource")); cl_assert_equal_s(conndata.scheme, "ssh"); @@ -255,7 +255,7 @@ void test_network_url_scp__malformed_ipv6_with_user(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_url_scp__invalid_addresses(void) +void test_url_scp__invalid_addresses(void) { /* Path is required */ cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse_scp(&conndata, @@ -314,8 +314,4 @@ void test_network_url_scp__invalid_addresses(void) "[git@[fe80::dcad:beff:fe00:0001]:42:/resource")); cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse_scp(&conndata, "[git@[fe80::dcad:beff:fe00:0001:42]:/resource")); - - /* Invalid character inside address */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "[fe8o::dcad:beff:fe00:0001]:/resource")); } diff --git a/tests/libgit2/network/url/valid.c b/tests/util/url/valid.c similarity index 94% rename from tests/libgit2/network/url/valid.c rename to tests/util/url/valid.c index 2b2cb7ba4..797b697bd 100644 --- a/tests/libgit2/network/url/valid.c +++ b/tests/util/url/valid.c @@ -1,7 +1,7 @@ #include "clar_libgit2.h" #include "net.h" -void test_network_url_valid__test(void) +void test_url_valid__test(void) { cl_assert(git_net_str_is_url("http://example.com/")); cl_assert(git_net_str_is_url("file://localhost/tmp/foo/"));