rugged 0.17.0.b7 → 0.18.0.b1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +1 -1
- data/README.md +88 -32
- data/ext/rugged/extconf.rb +4 -2
- data/ext/rugged/rugged.c +72 -10
- data/ext/rugged/rugged.h +14 -10
- data/ext/rugged/rugged_blob.c +8 -10
- data/ext/rugged/rugged_branch.c +11 -14
- data/ext/rugged/rugged_commit.c +31 -24
- data/ext/rugged/rugged_config.c +2 -2
- data/ext/rugged/rugged_index.c +133 -198
- data/ext/rugged/rugged_note.c +372 -0
- data/ext/rugged/rugged_object.c +50 -22
- data/ext/rugged/rugged_reference.c +122 -130
- data/ext/rugged/rugged_remote.c +72 -29
- data/ext/rugged/rugged_repo.c +402 -20
- data/ext/rugged/rugged_revwalk.c +7 -3
- data/ext/rugged/rugged_settings.c +110 -0
- data/ext/rugged/rugged_signature.c +23 -7
- data/ext/rugged/rugged_tag.c +32 -16
- data/ext/rugged/rugged_tree.c +44 -15
- data/lib/rugged.rb +1 -0
- data/lib/rugged/index.rb +8 -0
- data/lib/rugged/remote.rb +13 -0
- data/lib/rugged/repository.rb +3 -3
- data/lib/rugged/version.rb +1 -1
- data/test/blob_test.rb +13 -15
- data/test/branch_test.rb +32 -67
- data/test/commit_test.rb +50 -12
- data/test/config_test.rb +12 -11
- data/test/coverage/HEAD.json +1 -1
- data/test/coverage/cover.rb +40 -21
- data/test/errors_test.rb +34 -0
- data/test/fixtures/alternate/objects/14/6ae76773c91e3b1d00cf7a338ec55ae58297e2 +0 -0
- data/test/fixtures/alternate/objects/14/9c32d47e99d0a3572ff1e70a2e0051bbf347a9 +0 -0
- data/test/fixtures/alternate/objects/14/fb3108588f9421bf764041e5e3ac305eb6277f +0 -0
- data/test/fixtures/testrepo.git/logs/refs/notes/commits +1 -0
- data/test/fixtures/testrepo.git/objects/44/1034f860c1d5d90e4188d11ae0d325176869a8 +1 -0
- data/test/fixtures/testrepo.git/objects/60/d415052a33de2150bf68757f6461df4f563ae4 +0 -0
- data/test/fixtures/testrepo.git/objects/68/8a8f4ef7496901d15322972f96e212a9e466cc +1 -0
- data/test/fixtures/testrepo.git/objects/94/eca2de348d5f672faf56b0decafa5937e3235e +0 -0
- data/test/fixtures/testrepo.git/objects/9b/7384fe1676186192842f5d3e129457b62db9e3 +0 -0
- data/test/fixtures/testrepo.git/objects/b7/4713326bc972cc15751ed504dca6f6f3b91f7a +3 -0
- data/test/fixtures/testrepo.git/refs/notes/commits +1 -0
- data/test/index_test.rb +65 -69
- data/test/lib_test.rb +76 -11
- data/test/note_test.rb +158 -0
- data/test/object_test.rb +8 -11
- data/test/reference_test.rb +77 -85
- data/test/remote_test.rb +86 -8
- data/test/repo_pack_test.rb +9 -7
- data/test/repo_reset_test.rb +80 -0
- data/test/repo_test.rb +176 -53
- data/test/tag_test.rb +44 -7
- data/test/test_helper.rb +63 -35
- data/test/tree_test.rb +34 -13
- data/test/walker_test.rb +14 -14
- data/vendor/libgit2/Makefile.embed +1 -1
- data/vendor/libgit2/deps/http-parser/http_parser.c +974 -578
- data/vendor/libgit2/deps/http-parser/http_parser.h +106 -70
- data/vendor/libgit2/deps/regex/regcomp.c +7 -6
- data/vendor/libgit2/deps/regex/regex_internal.c +1 -1
- data/vendor/libgit2/deps/regex/regex_internal.h +12 -3
- data/vendor/libgit2/deps/regex/regexec.c +5 -5
- data/vendor/libgit2/include/git2.h +5 -1
- data/vendor/libgit2/include/git2/attr.h +4 -2
- data/vendor/libgit2/include/git2/blob.h +39 -12
- data/vendor/libgit2/include/git2/branch.h +123 -35
- data/vendor/libgit2/include/git2/checkout.h +206 -48
- data/vendor/libgit2/include/git2/clone.h +72 -27
- data/vendor/libgit2/include/git2/commit.h +20 -17
- data/vendor/libgit2/include/git2/common.h +67 -1
- data/vendor/libgit2/include/git2/config.h +81 -60
- data/vendor/libgit2/include/git2/cred_helpers.h +53 -0
- data/vendor/libgit2/include/git2/diff.h +459 -150
- data/vendor/libgit2/include/git2/errors.h +9 -1
- data/vendor/libgit2/include/git2/graph.h +41 -0
- data/vendor/libgit2/include/git2/ignore.h +7 -6
- data/vendor/libgit2/include/git2/index.h +323 -97
- data/vendor/libgit2/include/git2/indexer.h +27 -59
- data/vendor/libgit2/include/git2/inttypes.h +4 -0
- data/vendor/libgit2/include/git2/merge.h +13 -3
- data/vendor/libgit2/include/git2/message.h +14 -8
- data/vendor/libgit2/include/git2/net.h +9 -7
- data/vendor/libgit2/include/git2/notes.h +88 -29
- data/vendor/libgit2/include/git2/object.h +16 -6
- data/vendor/libgit2/include/git2/odb.h +80 -17
- data/vendor/libgit2/include/git2/odb_backend.h +47 -11
- data/vendor/libgit2/include/git2/oid.h +26 -17
- data/vendor/libgit2/include/git2/pack.h +62 -8
- data/vendor/libgit2/include/git2/push.h +131 -0
- data/vendor/libgit2/include/git2/refdb.h +103 -0
- data/vendor/libgit2/include/git2/refdb_backend.h +109 -0
- data/vendor/libgit2/include/git2/reflog.h +30 -21
- data/vendor/libgit2/include/git2/refs.h +215 -193
- data/vendor/libgit2/include/git2/refspec.h +22 -2
- data/vendor/libgit2/include/git2/remote.h +158 -37
- data/vendor/libgit2/include/git2/repository.h +150 -31
- data/vendor/libgit2/include/git2/reset.h +43 -9
- data/vendor/libgit2/include/git2/revparse.h +48 -4
- data/vendor/libgit2/include/git2/revwalk.h +25 -10
- data/vendor/libgit2/include/git2/signature.h +20 -12
- data/vendor/libgit2/include/git2/stash.h +121 -0
- data/vendor/libgit2/include/git2/status.h +122 -53
- data/vendor/libgit2/include/git2/strarray.h +17 -11
- data/vendor/libgit2/include/git2/submodule.h +42 -7
- data/vendor/libgit2/include/git2/tag.h +72 -59
- data/vendor/libgit2/include/git2/threads.h +4 -2
- data/vendor/libgit2/include/git2/trace.h +68 -0
- data/vendor/libgit2/include/git2/transport.h +328 -0
- data/vendor/libgit2/include/git2/tree.h +149 -120
- data/vendor/libgit2/include/git2/types.h +13 -12
- data/vendor/libgit2/include/git2/version.h +3 -3
- data/vendor/libgit2/src/amiga/map.c +2 -2
- data/vendor/libgit2/src/attr.c +58 -48
- data/vendor/libgit2/src/attr.h +4 -18
- data/vendor/libgit2/src/attr_file.c +30 -6
- data/vendor/libgit2/src/attr_file.h +6 -8
- data/vendor/libgit2/src/attrcache.h +24 -0
- data/vendor/libgit2/src/blob.c +30 -7
- data/vendor/libgit2/src/blob.h +1 -1
- data/vendor/libgit2/src/branch.c +361 -68
- data/vendor/libgit2/src/branch.h +17 -0
- data/vendor/libgit2/src/bswap.h +1 -1
- data/vendor/libgit2/src/buf_text.c +291 -0
- data/vendor/libgit2/src/buf_text.h +122 -0
- data/vendor/libgit2/src/buffer.c +27 -101
- data/vendor/libgit2/src/buffer.h +54 -39
- data/vendor/libgit2/src/cache.c +15 -6
- data/vendor/libgit2/src/cache.h +1 -1
- data/vendor/libgit2/src/cc-compat.h +3 -1
- data/vendor/libgit2/src/checkout.c +1165 -222
- data/vendor/libgit2/src/checkout.h +24 -0
- data/vendor/libgit2/src/clone.c +171 -86
- data/vendor/libgit2/src/commit.c +44 -45
- data/vendor/libgit2/src/commit.h +3 -3
- data/vendor/libgit2/src/commit_list.c +194 -0
- data/vendor/libgit2/src/commit_list.h +49 -0
- data/vendor/libgit2/src/common.h +44 -10
- data/vendor/libgit2/src/compress.c +1 -1
- data/vendor/libgit2/src/compress.h +1 -1
- data/vendor/libgit2/src/config.c +211 -124
- data/vendor/libgit2/src/config.h +23 -4
- data/vendor/libgit2/src/config_cache.c +2 -2
- data/vendor/libgit2/src/config_file.c +129 -53
- data/vendor/libgit2/src/config_file.h +10 -8
- data/vendor/libgit2/src/crlf.c +66 -67
- data/vendor/libgit2/src/date.c +12 -12
- data/vendor/libgit2/src/delta-apply.c +14 -1
- data/vendor/libgit2/src/delta-apply.h +18 -1
- data/vendor/libgit2/src/delta.c +40 -107
- data/vendor/libgit2/src/delta.h +19 -17
- data/vendor/libgit2/src/diff.c +347 -496
- data/vendor/libgit2/src/diff.h +27 -1
- data/vendor/libgit2/src/diff_output.c +564 -249
- data/vendor/libgit2/src/diff_output.h +15 -8
- data/vendor/libgit2/src/diff_tform.c +687 -0
- data/vendor/libgit2/src/errors.c +27 -36
- data/vendor/libgit2/src/fetch.c +13 -351
- data/vendor/libgit2/src/fetch.h +13 -3
- data/vendor/libgit2/src/fetchhead.c +295 -0
- data/vendor/libgit2/src/fetchhead.h +34 -0
- data/vendor/libgit2/src/filebuf.c +42 -15
- data/vendor/libgit2/src/filebuf.h +4 -2
- data/vendor/libgit2/src/fileops.c +466 -113
- data/vendor/libgit2/src/fileops.h +154 -28
- data/vendor/libgit2/src/filter.c +3 -75
- data/vendor/libgit2/src/filter.h +1 -29
- data/vendor/libgit2/src/fnmatch.c +1 -1
- data/vendor/libgit2/src/fnmatch.h +1 -1
- data/vendor/libgit2/src/global.c +54 -10
- data/vendor/libgit2/src/global.h +10 -1
- data/vendor/libgit2/src/graph.c +178 -0
- data/vendor/libgit2/src/hash.c +25 -52
- data/vendor/libgit2/src/hash.h +21 -9
- data/vendor/libgit2/src/{sha1/sha1.c → hash/hash_generic.c} +20 -12
- data/vendor/libgit2/src/hash/hash_generic.h +24 -0
- data/vendor/libgit2/src/hash/hash_openssl.h +45 -0
- data/vendor/libgit2/src/hash/hash_win32.c +291 -0
- data/vendor/libgit2/src/hash/hash_win32.h +140 -0
- data/vendor/libgit2/src/hashsig.c +368 -0
- data/vendor/libgit2/src/hashsig.h +72 -0
- data/vendor/libgit2/src/ignore.c +22 -15
- data/vendor/libgit2/src/ignore.h +6 -1
- data/vendor/libgit2/src/index.c +770 -171
- data/vendor/libgit2/src/index.h +13 -5
- data/vendor/libgit2/src/indexer.c +286 -431
- data/vendor/libgit2/src/iterator.c +854 -466
- data/vendor/libgit2/src/iterator.h +134 -109
- data/vendor/libgit2/src/map.h +1 -1
- data/vendor/libgit2/src/merge.c +296 -0
- data/vendor/libgit2/src/merge.h +22 -0
- data/vendor/libgit2/src/message.c +1 -1
- data/vendor/libgit2/src/message.h +1 -1
- data/vendor/libgit2/src/mwindow.c +35 -30
- data/vendor/libgit2/src/mwindow.h +2 -2
- data/vendor/libgit2/src/netops.c +162 -98
- data/vendor/libgit2/src/netops.h +50 -15
- data/vendor/libgit2/src/notes.c +109 -58
- data/vendor/libgit2/src/notes.h +2 -1
- data/vendor/libgit2/src/object.c +46 -57
- data/vendor/libgit2/src/object.h +1 -8
- data/vendor/libgit2/src/odb.c +151 -40
- data/vendor/libgit2/src/odb.h +5 -1
- data/vendor/libgit2/src/odb_loose.c +4 -5
- data/vendor/libgit2/src/odb_pack.c +122 -80
- data/vendor/libgit2/src/offmap.h +65 -0
- data/vendor/libgit2/src/oid.c +12 -4
- data/vendor/libgit2/src/oidmap.h +1 -1
- data/vendor/libgit2/src/pack-objects.c +88 -61
- data/vendor/libgit2/src/pack-objects.h +8 -8
- data/vendor/libgit2/src/pack.c +293 -28
- data/vendor/libgit2/src/pack.h +49 -4
- data/vendor/libgit2/src/path.c +103 -14
- data/vendor/libgit2/src/path.h +23 -7
- data/vendor/libgit2/src/pathspec.c +168 -0
- data/vendor/libgit2/src/pathspec.h +40 -0
- data/vendor/libgit2/src/pool.c +29 -4
- data/vendor/libgit2/src/pool.h +8 -1
- data/vendor/libgit2/src/posix.c +26 -27
- data/vendor/libgit2/src/posix.h +2 -3
- data/vendor/libgit2/src/pqueue.c +23 -1
- data/vendor/libgit2/src/pqueue.h +23 -1
- data/vendor/libgit2/src/push.c +653 -0
- data/vendor/libgit2/src/push.h +51 -0
- data/vendor/libgit2/src/refdb.c +185 -0
- data/vendor/libgit2/src/refdb.h +46 -0
- data/vendor/libgit2/src/refdb_fs.c +1024 -0
- data/vendor/libgit2/src/refdb_fs.h +15 -0
- data/vendor/libgit2/src/reflog.c +77 -45
- data/vendor/libgit2/src/reflog.h +1 -3
- data/vendor/libgit2/src/refs.c +366 -1326
- data/vendor/libgit2/src/refs.h +22 -13
- data/vendor/libgit2/src/refspec.c +46 -7
- data/vendor/libgit2/src/refspec.h +11 -1
- data/vendor/libgit2/src/remote.c +758 -120
- data/vendor/libgit2/src/remote.h +10 -5
- data/vendor/libgit2/src/repo_template.h +6 -6
- data/vendor/libgit2/src/repository.c +315 -96
- data/vendor/libgit2/src/repository.h +5 -3
- data/vendor/libgit2/src/reset.c +99 -81
- data/vendor/libgit2/src/revparse.c +157 -84
- data/vendor/libgit2/src/revwalk.c +68 -470
- data/vendor/libgit2/src/revwalk.h +44 -0
- data/vendor/libgit2/src/sha1_lookup.c +1 -1
- data/vendor/libgit2/src/sha1_lookup.h +1 -1
- data/vendor/libgit2/src/signature.c +68 -200
- data/vendor/libgit2/src/signature.h +1 -1
- data/vendor/libgit2/src/stash.c +663 -0
- data/vendor/libgit2/src/status.c +101 -79
- data/vendor/libgit2/src/strmap.h +1 -1
- data/vendor/libgit2/src/submodule.c +67 -51
- data/vendor/libgit2/src/submodule.h +1 -1
- data/vendor/libgit2/src/tag.c +35 -29
- data/vendor/libgit2/src/tag.h +1 -1
- data/vendor/libgit2/src/thread-utils.c +1 -1
- data/vendor/libgit2/src/thread-utils.h +2 -2
- data/vendor/libgit2/src/trace.c +39 -0
- data/vendor/libgit2/src/trace.h +56 -0
- data/vendor/libgit2/src/transport.c +81 -34
- data/vendor/libgit2/src/transports/cred.c +60 -0
- data/vendor/libgit2/src/transports/cred_helpers.c +49 -0
- data/vendor/libgit2/src/transports/git.c +234 -127
- data/vendor/libgit2/src/transports/http.c +761 -433
- data/vendor/libgit2/src/transports/local.c +460 -64
- data/vendor/libgit2/src/transports/smart.c +345 -0
- data/vendor/libgit2/src/transports/smart.h +179 -0
- data/vendor/libgit2/src/{pkt.c → transports/smart_pkt.c} +131 -12
- data/vendor/libgit2/src/transports/smart_protocol.c +856 -0
- data/vendor/libgit2/src/transports/winhttp.c +1136 -0
- data/vendor/libgit2/src/tree-cache.c +2 -2
- data/vendor/libgit2/src/tree-cache.h +1 -1
- data/vendor/libgit2/src/tree.c +239 -166
- data/vendor/libgit2/src/tree.h +11 -2
- data/vendor/libgit2/src/tsort.c +39 -23
- data/vendor/libgit2/src/unix/map.c +1 -1
- data/vendor/libgit2/src/unix/posix.h +12 -2
- data/vendor/libgit2/src/unix/realpath.c +30 -0
- data/vendor/libgit2/src/util.c +250 -13
- data/vendor/libgit2/src/util.h +71 -14
- data/vendor/libgit2/src/vector.c +123 -60
- data/vendor/libgit2/src/vector.h +24 -22
- data/vendor/libgit2/src/win32/dir.c +1 -1
- data/vendor/libgit2/src/win32/dir.h +1 -1
- data/vendor/libgit2/src/win32/error.c +77 -0
- data/vendor/libgit2/src/win32/error.h +13 -0
- data/vendor/libgit2/src/win32/findfile.c +143 -54
- data/vendor/libgit2/src/win32/findfile.h +10 -6
- data/vendor/libgit2/src/win32/map.c +1 -1
- data/vendor/libgit2/src/win32/mingw-compat.h +1 -1
- data/vendor/libgit2/src/win32/msvc-compat.h +10 -1
- data/vendor/libgit2/src/win32/posix.h +10 -1
- data/vendor/libgit2/src/win32/posix_w32.c +132 -63
- data/vendor/libgit2/src/win32/precompiled.c +1 -1
- data/vendor/libgit2/src/win32/pthread.c +1 -1
- data/vendor/libgit2/src/win32/pthread.h +1 -1
- data/vendor/libgit2/src/win32/utf-conv.c +5 -5
- data/vendor/libgit2/src/win32/utf-conv.h +3 -3
- data/vendor/libgit2/src/win32/version.h +20 -0
- metadata +308 -252
- data/test/fixtures/testrepo.git/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 +0 -0
- data/test/fixtures/testrepo.git/objects/7f/043268ea43ce18e3540acaabf9e090c91965b0 +0 -0
- data/test/fixtures/testrepo.git/objects/a3/e05719b428a2d0ed7a55c4ce53dcc5768c6d5e +0 -0
- data/test/index_test.rb~ +0 -218
- data/vendor/libgit2/src/pkt.h +0 -91
- data/vendor/libgit2/src/ppc/sha1.c +0 -70
- data/vendor/libgit2/src/ppc/sha1.h +0 -26
- data/vendor/libgit2/src/protocol.c +0 -110
- data/vendor/libgit2/src/protocol.h +0 -21
- data/vendor/libgit2/src/sha1.h +0 -33
- data/vendor/libgit2/src/transport.h +0 -148
data/vendor/libgit2/src/ignore.h
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
* Copyright (C)
|
2
|
+
* Copyright (C) the libgit2 contributors. All rights reserved.
|
3
3
|
*
|
4
4
|
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
5
5
|
* a Linking Exception. For full terms see the included COPYING file.
|
@@ -9,6 +9,11 @@
|
|
9
9
|
|
10
10
|
#include "repository.h"
|
11
11
|
#include "vector.h"
|
12
|
+
#include "attr_file.h"
|
13
|
+
|
14
|
+
#define GIT_IGNORE_FILE ".gitignore"
|
15
|
+
#define GIT_IGNORE_FILE_INREPO "info/exclude"
|
16
|
+
#define GIT_IGNORE_FILE_XDG "ignore"
|
12
17
|
|
13
18
|
/* The git_ignores structure maintains three sets of ignores:
|
14
19
|
* - internal ignores
|
data/vendor/libgit2/src/index.c
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
* Copyright (C)
|
2
|
+
* Copyright (C) the libgit2 contributors. All rights reserved.
|
3
3
|
*
|
4
4
|
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
5
5
|
* a Linking Exception. For full terms see the included COPYING file.
|
@@ -13,6 +13,8 @@
|
|
13
13
|
#include "tree.h"
|
14
14
|
#include "tree-cache.h"
|
15
15
|
#include "hash.h"
|
16
|
+
#include "iterator.h"
|
17
|
+
#include "pathspec.h"
|
16
18
|
#include "git2/odb.h"
|
17
19
|
#include "git2/oid.h"
|
18
20
|
#include "git2/blob.h"
|
@@ -81,62 +83,140 @@ struct entry_long {
|
|
81
83
|
char path[1]; /* arbitrary length */
|
82
84
|
};
|
83
85
|
|
86
|
+
struct entry_srch_key {
|
87
|
+
const char *path;
|
88
|
+
int stage;
|
89
|
+
};
|
90
|
+
|
84
91
|
/* local declarations */
|
85
92
|
static size_t read_extension(git_index *index, const char *buffer, size_t buffer_size);
|
86
93
|
static size_t read_entry(git_index_entry *dest, const void *buffer, size_t buffer_size);
|
87
94
|
static int read_header(struct index_header *dest, const void *buffer);
|
88
95
|
|
89
96
|
static int parse_index(git_index *index, const char *buffer, size_t buffer_size);
|
90
|
-
static
|
97
|
+
static bool is_index_extended(git_index *index);
|
91
98
|
static int write_index(git_index *index, git_filebuf *file);
|
92
99
|
|
100
|
+
static int index_find(size_t *at_pos, git_index *index, const char *path, int stage);
|
101
|
+
|
93
102
|
static void index_entry_free(git_index_entry *entry);
|
103
|
+
static void index_entry_reuc_free(git_index_reuc_entry *reuc);
|
104
|
+
|
105
|
+
GIT_INLINE(int) index_entry_stage(const git_index_entry *entry)
|
106
|
+
{
|
107
|
+
return (entry->flags & GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT;
|
108
|
+
}
|
94
109
|
|
95
110
|
static int index_srch(const void *key, const void *array_member)
|
96
111
|
{
|
112
|
+
const struct entry_srch_key *srch_key = key;
|
97
113
|
const git_index_entry *entry = array_member;
|
114
|
+
int ret;
|
115
|
+
|
116
|
+
ret = strcmp(srch_key->path, entry->path);
|
117
|
+
|
118
|
+
if (ret == 0)
|
119
|
+
ret = srch_key->stage - index_entry_stage(entry);
|
98
120
|
|
99
|
-
return
|
121
|
+
return ret;
|
100
122
|
}
|
101
123
|
|
102
124
|
static int index_isrch(const void *key, const void *array_member)
|
103
125
|
{
|
126
|
+
const struct entry_srch_key *srch_key = key;
|
104
127
|
const git_index_entry *entry = array_member;
|
128
|
+
int ret;
|
129
|
+
|
130
|
+
ret = strcasecmp(srch_key->path, entry->path);
|
131
|
+
|
132
|
+
if (ret == 0)
|
133
|
+
ret = srch_key->stage - index_entry_stage(entry);
|
105
134
|
|
106
|
-
return
|
135
|
+
return ret;
|
136
|
+
}
|
137
|
+
|
138
|
+
static int index_cmp_path(const void *a, const void *b)
|
139
|
+
{
|
140
|
+
return strcmp((const char *)a, (const char *)b);
|
141
|
+
}
|
142
|
+
|
143
|
+
static int index_icmp_path(const void *a, const void *b)
|
144
|
+
{
|
145
|
+
return strcasecmp((const char *)a, (const char *)b);
|
146
|
+
}
|
147
|
+
|
148
|
+
static int index_srch_path(const void *path, const void *array_member)
|
149
|
+
{
|
150
|
+
const git_index_entry *entry = array_member;
|
151
|
+
|
152
|
+
return strcmp((const char *)path, entry->path);
|
153
|
+
}
|
154
|
+
|
155
|
+
static int index_isrch_path(const void *path, const void *array_member)
|
156
|
+
{
|
157
|
+
const git_index_entry *entry = array_member;
|
158
|
+
|
159
|
+
return strcasecmp((const char *)path, entry->path);
|
107
160
|
}
|
108
161
|
|
109
162
|
static int index_cmp(const void *a, const void *b)
|
110
163
|
{
|
164
|
+
int diff;
|
111
165
|
const git_index_entry *entry_a = a;
|
112
166
|
const git_index_entry *entry_b = b;
|
113
167
|
|
114
|
-
|
168
|
+
diff = strcmp(entry_a->path, entry_b->path);
|
169
|
+
|
170
|
+
if (diff == 0)
|
171
|
+
diff = (index_entry_stage(entry_a) - index_entry_stage(entry_b));
|
172
|
+
|
173
|
+
return diff;
|
115
174
|
}
|
116
175
|
|
117
176
|
static int index_icmp(const void *a, const void *b)
|
118
177
|
{
|
178
|
+
int diff;
|
119
179
|
const git_index_entry *entry_a = a;
|
120
180
|
const git_index_entry *entry_b = b;
|
121
181
|
|
122
|
-
|
182
|
+
diff = strcasecmp(entry_a->path, entry_b->path);
|
183
|
+
|
184
|
+
if (diff == 0)
|
185
|
+
diff = (index_entry_stage(entry_a) - index_entry_stage(entry_b));
|
186
|
+
|
187
|
+
return diff;
|
188
|
+
}
|
189
|
+
|
190
|
+
static int reuc_srch(const void *key, const void *array_member)
|
191
|
+
{
|
192
|
+
const git_index_reuc_entry *reuc = array_member;
|
193
|
+
|
194
|
+
return strcmp(key, reuc->path);
|
123
195
|
}
|
124
196
|
|
125
|
-
static int
|
197
|
+
static int reuc_isrch(const void *key, const void *array_member)
|
126
198
|
{
|
127
|
-
const
|
199
|
+
const git_index_reuc_entry *reuc = array_member;
|
128
200
|
|
129
|
-
return
|
201
|
+
return strcasecmp(key, reuc->path);
|
130
202
|
}
|
131
203
|
|
132
|
-
static int
|
204
|
+
static int reuc_cmp(const void *a, const void *b)
|
133
205
|
{
|
134
|
-
const
|
135
|
-
const
|
206
|
+
const git_index_reuc_entry *info_a = a;
|
207
|
+
const git_index_reuc_entry *info_b = b;
|
136
208
|
|
137
209
|
return strcmp(info_a->path, info_b->path);
|
138
210
|
}
|
139
211
|
|
212
|
+
static int reuc_icmp(const void *a, const void *b)
|
213
|
+
{
|
214
|
+
const git_index_reuc_entry *info_a = a;
|
215
|
+
const git_index_reuc_entry *info_b = b;
|
216
|
+
|
217
|
+
return strcasecmp(info_a->path, info_b->path);
|
218
|
+
}
|
219
|
+
|
140
220
|
static unsigned int index_create_mode(unsigned int mode)
|
141
221
|
{
|
142
222
|
if (S_ISLNK(mode))
|
@@ -162,54 +242,66 @@ static unsigned int index_merge_mode(
|
|
162
242
|
return index_create_mode(mode);
|
163
243
|
}
|
164
244
|
|
165
|
-
|
245
|
+
void git_index__set_ignore_case(git_index *index, bool ignore_case)
|
166
246
|
{
|
247
|
+
index->ignore_case = ignore_case;
|
248
|
+
|
167
249
|
index->entries._cmp = ignore_case ? index_icmp : index_cmp;
|
250
|
+
index->entries_cmp_path = ignore_case ? index_icmp_path : index_cmp_path;
|
168
251
|
index->entries_search = ignore_case ? index_isrch : index_srch;
|
252
|
+
index->entries_search_path = ignore_case ? index_isrch_path : index_srch_path;
|
169
253
|
index->entries.sorted = 0;
|
170
254
|
git_vector_sort(&index->entries);
|
255
|
+
|
256
|
+
index->reuc._cmp = ignore_case ? reuc_icmp : reuc_cmp;
|
257
|
+
index->reuc_search = ignore_case ? reuc_isrch : reuc_srch;
|
258
|
+
index->reuc.sorted = 0;
|
259
|
+
git_vector_sort(&index->reuc);
|
171
260
|
}
|
172
261
|
|
173
262
|
int git_index_open(git_index **index_out, const char *index_path)
|
174
263
|
{
|
175
264
|
git_index *index;
|
176
265
|
|
177
|
-
assert(index_out
|
266
|
+
assert(index_out);
|
178
267
|
|
179
268
|
index = git__calloc(1, sizeof(git_index));
|
180
269
|
GITERR_CHECK_ALLOC(index);
|
181
270
|
|
182
|
-
|
183
|
-
|
271
|
+
if (index_path != NULL) {
|
272
|
+
index->index_file_path = git__strdup(index_path);
|
273
|
+
GITERR_CHECK_ALLOC(index->index_file_path);
|
274
|
+
|
275
|
+
/* Check if index file is stored on disk already */
|
276
|
+
if (git_path_exists(index->index_file_path) == true)
|
277
|
+
index->on_disk = 1;
|
278
|
+
}
|
184
279
|
|
185
|
-
if (git_vector_init(&index->entries, 32, index_cmp) < 0
|
280
|
+
if (git_vector_init(&index->entries, 32, index_cmp) < 0 ||
|
281
|
+
git_vector_init(&index->reuc, 32, reuc_cmp) < 0)
|
186
282
|
return -1;
|
187
283
|
|
284
|
+
index->entries_cmp_path = index_cmp_path;
|
188
285
|
index->entries_search = index_srch;
|
189
|
-
|
190
|
-
|
191
|
-
if (git_path_exists(index->index_file_path) == true)
|
192
|
-
index->on_disk = 1;
|
286
|
+
index->entries_search_path = index_srch_path;
|
287
|
+
index->reuc_search = reuc_srch;
|
193
288
|
|
194
289
|
*index_out = index;
|
195
290
|
GIT_REFCOUNT_INC(index);
|
196
|
-
|
291
|
+
|
292
|
+
return (index_path != NULL) ? git_index_read(index) : 0;
|
197
293
|
}
|
198
294
|
|
199
|
-
|
295
|
+
int git_index_new(git_index **out)
|
200
296
|
{
|
201
|
-
|
202
|
-
|
297
|
+
return git_index_open(out, NULL);
|
298
|
+
}
|
203
299
|
|
300
|
+
static void index_free(git_index *index)
|
301
|
+
{
|
204
302
|
git_index_clear(index);
|
205
|
-
git_vector_foreach(&index->entries, i, e) {
|
206
|
-
index_entry_free(e);
|
207
|
-
}
|
208
303
|
git_vector_free(&index->entries);
|
209
|
-
|
210
|
-
index_entry_free(e);
|
211
|
-
}
|
212
|
-
git_vector_free(&index->unmerged);
|
304
|
+
git_vector_free(&index->reuc);
|
213
305
|
|
214
306
|
git__free(index->index_file_path);
|
215
307
|
git__free(index);
|
@@ -225,7 +317,7 @@ void git_index_free(git_index *index)
|
|
225
317
|
|
226
318
|
void git_index_clear(git_index *index)
|
227
319
|
{
|
228
|
-
|
320
|
+
size_t i;
|
229
321
|
|
230
322
|
assert(index);
|
231
323
|
|
@@ -235,22 +327,22 @@ void git_index_clear(git_index *index)
|
|
235
327
|
git__free(e->path);
|
236
328
|
git__free(e);
|
237
329
|
}
|
238
|
-
|
239
|
-
for (i = 0; i < index->unmerged.length; ++i) {
|
240
|
-
git_index_entry_unmerged *e;
|
241
|
-
e = git_vector_get(&index->unmerged, i);
|
242
|
-
git__free(e->path);
|
243
|
-
git__free(e);
|
244
|
-
}
|
245
|
-
|
246
330
|
git_vector_clear(&index->entries);
|
247
|
-
|
248
|
-
index
|
331
|
+
|
332
|
+
git_index_reuc_clear(index);
|
333
|
+
|
334
|
+
git_futils_filestamp_set(&index->stamp, NULL);
|
249
335
|
|
250
336
|
git_tree_cache_free(index->tree);
|
251
337
|
index->tree = NULL;
|
252
338
|
}
|
253
339
|
|
340
|
+
static int create_index_error(int error, const char *msg)
|
341
|
+
{
|
342
|
+
giterr_set(GITERR_INDEX, msg);
|
343
|
+
return error;
|
344
|
+
}
|
345
|
+
|
254
346
|
int git_index_set_caps(git_index *index, unsigned int caps)
|
255
347
|
{
|
256
348
|
int old_ignore_case;
|
@@ -265,11 +357,8 @@ int git_index_set_caps(git_index *index, unsigned int caps)
|
|
265
357
|
|
266
358
|
if (INDEX_OWNER(index) == NULL ||
|
267
359
|
git_repository_config__weakptr(&cfg, INDEX_OWNER(index)) < 0)
|
268
|
-
|
269
|
-
|
270
|
-
"Cannot get repository config to set index caps");
|
271
|
-
return -1;
|
272
|
-
}
|
360
|
+
return create_index_error(-1,
|
361
|
+
"Cannot get repository config to set index caps");
|
273
362
|
|
274
363
|
if (git_config_get_bool(&val, cfg, "core.ignorecase") == 0)
|
275
364
|
index->ignore_case = (val != 0);
|
@@ -284,9 +373,8 @@ int git_index_set_caps(git_index *index, unsigned int caps)
|
|
284
373
|
index->no_symlinks = ((caps & GIT_INDEXCAP_NO_SYMLINKS) != 0);
|
285
374
|
}
|
286
375
|
|
287
|
-
if (old_ignore_case != index->ignore_case)
|
288
|
-
|
289
|
-
index_set_ignore_case(index, index->ignore_case);
|
376
|
+
if (old_ignore_case != index->ignore_case) {
|
377
|
+
git_index__set_ignore_case(index, index->ignore_case);
|
290
378
|
}
|
291
379
|
|
292
380
|
return 0;
|
@@ -301,11 +389,13 @@ unsigned int git_index_caps(const git_index *index)
|
|
301
389
|
|
302
390
|
int git_index_read(git_index *index)
|
303
391
|
{
|
304
|
-
int error, updated;
|
392
|
+
int error = 0, updated;
|
305
393
|
git_buf buffer = GIT_BUF_INIT;
|
306
|
-
|
394
|
+
git_futils_filestamp stamp = {0};
|
307
395
|
|
308
|
-
|
396
|
+
if (!index->index_file_path)
|
397
|
+
return create_index_error(-1,
|
398
|
+
"Failed to read index: The index is in-memory only");
|
309
399
|
|
310
400
|
if (!index->on_disk || git_path_exists(index->index_file_path) == false) {
|
311
401
|
git_index_clear(index);
|
@@ -313,33 +403,35 @@ int git_index_read(git_index *index)
|
|
313
403
|
return 0;
|
314
404
|
}
|
315
405
|
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
406
|
+
updated = git_futils_filestamp_check(&stamp, index->index_file_path);
|
407
|
+
if (updated <= 0)
|
408
|
+
return updated;
|
409
|
+
|
410
|
+
error = git_futils_readbuffer(&buffer, index->index_file_path);
|
320
411
|
if (error < 0)
|
321
412
|
return error;
|
322
413
|
|
323
|
-
|
324
|
-
|
325
|
-
error = parse_index(index, buffer.ptr, buffer.size);
|
326
|
-
|
327
|
-
if (!error)
|
328
|
-
index->last_modified = mtime;
|
414
|
+
git_index_clear(index);
|
415
|
+
error = parse_index(index, buffer.ptr, buffer.size);
|
329
416
|
|
330
|
-
|
331
|
-
|
417
|
+
if (!error)
|
418
|
+
git_futils_filestamp_set(&index->stamp, &stamp);
|
332
419
|
|
420
|
+
git_buf_free(&buffer);
|
333
421
|
return error;
|
334
422
|
}
|
335
423
|
|
336
424
|
int git_index_write(git_index *index)
|
337
425
|
{
|
338
426
|
git_filebuf file = GIT_FILEBUF_INIT;
|
339
|
-
struct stat indexst;
|
340
427
|
int error;
|
341
428
|
|
429
|
+
if (!index->index_file_path)
|
430
|
+
return create_index_error(-1,
|
431
|
+
"Failed to read index: The index is in-memory only");
|
432
|
+
|
342
433
|
git_vector_sort(&index->entries);
|
434
|
+
git_vector_sort(&index->reuc);
|
343
435
|
|
344
436
|
if ((error = git_filebuf_open(
|
345
437
|
&file, index->index_file_path, GIT_FILEBUF_HASH_CONTENTS)) < 0)
|
@@ -353,33 +445,65 @@ int git_index_write(git_index *index)
|
|
353
445
|
if ((error = git_filebuf_commit(&file, GIT_INDEX_FILE_MODE)) < 0)
|
354
446
|
return error;
|
355
447
|
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
}
|
448
|
+
error = git_futils_filestamp_check(&index->stamp, index->index_file_path);
|
449
|
+
if (error < 0)
|
450
|
+
return error;
|
360
451
|
|
452
|
+
index->on_disk = 1;
|
361
453
|
return 0;
|
362
454
|
}
|
363
455
|
|
364
|
-
|
456
|
+
int git_index_write_tree(git_oid *oid, git_index *index)
|
365
457
|
{
|
366
|
-
|
367
|
-
|
458
|
+
git_repository *repo;
|
459
|
+
|
460
|
+
assert(oid && index);
|
461
|
+
|
462
|
+
repo = INDEX_OWNER(index);
|
463
|
+
|
464
|
+
if (repo == NULL)
|
465
|
+
return create_index_error(-1, "Failed to write tree. "
|
466
|
+
"The index file is not backed up by an existing repository");
|
467
|
+
|
468
|
+
return git_tree__write_index(oid, index, repo);
|
368
469
|
}
|
369
470
|
|
370
|
-
|
471
|
+
int git_index_write_tree_to(git_oid *oid, git_index *index, git_repository *repo)
|
472
|
+
{
|
473
|
+
assert(oid && index && repo);
|
474
|
+
return git_tree__write_index(oid, index, repo);
|
475
|
+
}
|
476
|
+
|
477
|
+
size_t git_index_entrycount(const git_index *index)
|
371
478
|
{
|
372
479
|
assert(index);
|
373
|
-
return
|
480
|
+
return index->entries.length;
|
374
481
|
}
|
375
482
|
|
376
|
-
git_index_entry *
|
483
|
+
const git_index_entry *git_index_get_byindex(
|
484
|
+
git_index *index, size_t n)
|
377
485
|
{
|
486
|
+
assert(index);
|
378
487
|
git_vector_sort(&index->entries);
|
379
488
|
return git_vector_get(&index->entries, n);
|
380
489
|
}
|
381
490
|
|
382
|
-
|
491
|
+
const git_index_entry *git_index_get_bypath(
|
492
|
+
git_index *index, const char *path, int stage)
|
493
|
+
{
|
494
|
+
size_t pos;
|
495
|
+
|
496
|
+
assert(index);
|
497
|
+
|
498
|
+
git_vector_sort(&index->entries);
|
499
|
+
|
500
|
+
if (index_find(&pos, index, path, stage) < 0)
|
501
|
+
return NULL;
|
502
|
+
|
503
|
+
return git_index_get_byindex(index, pos);
|
504
|
+
}
|
505
|
+
|
506
|
+
void git_index_entry__init_from_stat(git_index_entry *entry, struct stat *st)
|
383
507
|
{
|
384
508
|
entry->ctime.seconds = (git_time_t)st->st_ctime;
|
385
509
|
entry->mtime.seconds = (git_time_t)st->st_mtime;
|
@@ -393,7 +517,23 @@ void git_index__init_entry_from_stat(struct stat *st, git_index_entry *entry)
|
|
393
517
|
entry->file_size = st->st_size;
|
394
518
|
}
|
395
519
|
|
396
|
-
|
520
|
+
int git_index_entry__cmp(const void *a, const void *b)
|
521
|
+
{
|
522
|
+
const git_index_entry *entry_a = a;
|
523
|
+
const git_index_entry *entry_b = b;
|
524
|
+
|
525
|
+
return strcmp(entry_a->path, entry_b->path);
|
526
|
+
}
|
527
|
+
|
528
|
+
int git_index_entry__cmp_icase(const void *a, const void *b)
|
529
|
+
{
|
530
|
+
const git_index_entry *entry_a = a;
|
531
|
+
const git_index_entry *entry_b = b;
|
532
|
+
|
533
|
+
return strcasecmp(entry_a->path, entry_b->path);
|
534
|
+
}
|
535
|
+
|
536
|
+
static int index_entry_init(git_index_entry **entry_out, git_index *index, const char *rel_path)
|
397
537
|
{
|
398
538
|
git_index_entry *entry = NULL;
|
399
539
|
struct stat st;
|
@@ -402,15 +542,16 @@ static int index_entry_init(git_index_entry **entry_out, git_index *index, const
|
|
402
542
|
git_buf full_path = GIT_BUF_INIT;
|
403
543
|
int error;
|
404
544
|
|
405
|
-
|
545
|
+
if (INDEX_OWNER(index) == NULL)
|
546
|
+
return create_index_error(-1,
|
547
|
+
"Could not initialize index entry. "
|
548
|
+
"Index is not backed up by an existing repository.");
|
406
549
|
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
550
|
+
workdir = git_repository_workdir(INDEX_OWNER(index));
|
551
|
+
|
552
|
+
if (!workdir)
|
553
|
+
return create_index_error(GIT_EBAREREPO,
|
411
554
|
"Could not initialize index entry. Repository is bare");
|
412
|
-
return -1;
|
413
|
-
}
|
414
555
|
|
415
556
|
if ((error = git_buf_joinpath(&full_path, workdir, rel_path)) < 0)
|
416
557
|
return error;
|
@@ -427,16 +568,15 @@ static int index_entry_init(git_index_entry **entry_out, git_index *index, const
|
|
427
568
|
*/
|
428
569
|
|
429
570
|
/* write the blob to disk and get the oid */
|
430
|
-
if ((error =
|
571
|
+
if ((error = git_blob_create_fromworkdir(&oid, INDEX_OWNER(index), rel_path)) < 0)
|
431
572
|
return error;
|
432
573
|
|
433
574
|
entry = git__calloc(1, sizeof(git_index_entry));
|
434
575
|
GITERR_CHECK_ALLOC(entry);
|
435
576
|
|
436
|
-
|
577
|
+
git_index_entry__init_from_stat(entry, &st);
|
437
578
|
|
438
579
|
entry->oid = oid;
|
439
|
-
entry->flags |= (stage << GIT_IDXENTRY_STAGESHIFT);
|
440
580
|
entry->path = git__strdup(rel_path);
|
441
581
|
GITERR_CHECK_ALLOC(entry->path);
|
442
582
|
|
@@ -444,6 +584,46 @@ static int index_entry_init(git_index_entry **entry_out, git_index *index, const
|
|
444
584
|
return 0;
|
445
585
|
}
|
446
586
|
|
587
|
+
static int index_entry_reuc_init(git_index_reuc_entry **reuc_out,
|
588
|
+
const char *path,
|
589
|
+
int ancestor_mode, git_oid *ancestor_oid,
|
590
|
+
int our_mode, git_oid *our_oid, int their_mode, git_oid *their_oid)
|
591
|
+
{
|
592
|
+
git_index_reuc_entry *reuc = NULL;
|
593
|
+
|
594
|
+
assert(reuc_out && path);
|
595
|
+
|
596
|
+
*reuc_out = NULL;
|
597
|
+
|
598
|
+
reuc = git__calloc(1, sizeof(git_index_reuc_entry));
|
599
|
+
GITERR_CHECK_ALLOC(reuc);
|
600
|
+
|
601
|
+
reuc->path = git__strdup(path);
|
602
|
+
if (reuc->path == NULL)
|
603
|
+
return -1;
|
604
|
+
|
605
|
+
if ((reuc->mode[0] = ancestor_mode) > 0)
|
606
|
+
git_oid_cpy(&reuc->oid[0], ancestor_oid);
|
607
|
+
|
608
|
+
if ((reuc->mode[1] = our_mode) > 0)
|
609
|
+
git_oid_cpy(&reuc->oid[1], our_oid);
|
610
|
+
|
611
|
+
if ((reuc->mode[2] = their_mode) > 0)
|
612
|
+
git_oid_cpy(&reuc->oid[2], their_oid);
|
613
|
+
|
614
|
+
*reuc_out = reuc;
|
615
|
+
return 0;
|
616
|
+
}
|
617
|
+
|
618
|
+
static void index_entry_reuc_free(git_index_reuc_entry *reuc)
|
619
|
+
{
|
620
|
+
if (!reuc)
|
621
|
+
return;
|
622
|
+
|
623
|
+
git__free(reuc->path);
|
624
|
+
git__free(reuc);
|
625
|
+
}
|
626
|
+
|
447
627
|
static git_index_entry *index_entry_dup(const git_index_entry *source_entry)
|
448
628
|
{
|
449
629
|
git_index_entry *entry;
|
@@ -472,8 +652,7 @@ static void index_entry_free(git_index_entry *entry)
|
|
472
652
|
|
473
653
|
static int index_insert(git_index *index, git_index_entry *entry, int replace)
|
474
654
|
{
|
475
|
-
size_t path_length;
|
476
|
-
int position;
|
655
|
+
size_t path_length, position;
|
477
656
|
git_index_entry **existing = NULL;
|
478
657
|
|
479
658
|
assert(index && entry && entry->path != NULL);
|
@@ -486,10 +665,10 @@ static int index_insert(git_index *index, git_index_entry *entry, int replace)
|
|
486
665
|
if (path_length < GIT_IDXENTRY_NAMEMASK)
|
487
666
|
entry->flags |= path_length & GIT_IDXENTRY_NAMEMASK;
|
488
667
|
else
|
489
|
-
entry->flags |= GIT_IDXENTRY_NAMEMASK
|
668
|
+
entry->flags |= GIT_IDXENTRY_NAMEMASK;
|
490
669
|
|
491
670
|
/* look if an entry with this path already exists */
|
492
|
-
if ((position
|
671
|
+
if (!index_find(&position, index, entry->path, index_entry_stage(entry))) {
|
493
672
|
existing = (git_index_entry **)&index->entries.contents[position];
|
494
673
|
|
495
674
|
/* update filemode to existing values if stat is not trusted */
|
@@ -510,34 +689,71 @@ static int index_insert(git_index *index, git_index_entry *entry, int replace)
|
|
510
689
|
return 0;
|
511
690
|
}
|
512
691
|
|
513
|
-
static int
|
692
|
+
static int index_conflict_to_reuc(git_index *index, const char *path)
|
514
693
|
{
|
515
|
-
git_index_entry *
|
694
|
+
git_index_entry *conflict_entries[3];
|
695
|
+
int ancestor_mode, our_mode, their_mode;
|
696
|
+
git_oid *ancestor_oid, *our_oid, *their_oid;
|
516
697
|
int ret;
|
517
698
|
|
518
|
-
if ((ret =
|
519
|
-
|
520
|
-
{
|
521
|
-
index_entry_free(entry);
|
699
|
+
if ((ret = git_index_conflict_get(&conflict_entries[0],
|
700
|
+
&conflict_entries[1], &conflict_entries[2], index, path)) < 0)
|
522
701
|
return ret;
|
523
|
-
}
|
524
702
|
|
525
|
-
|
526
|
-
|
703
|
+
ancestor_mode = conflict_entries[0] == NULL ? 0 : conflict_entries[0]->mode;
|
704
|
+
our_mode = conflict_entries[1] == NULL ? 0 : conflict_entries[1]->mode;
|
705
|
+
their_mode = conflict_entries[2] == NULL ? 0 : conflict_entries[2]->mode;
|
706
|
+
|
707
|
+
ancestor_oid = conflict_entries[0] == NULL ? NULL : &conflict_entries[0]->oid;
|
708
|
+
our_oid = conflict_entries[1] == NULL ? NULL : &conflict_entries[1]->oid;
|
709
|
+
their_oid = conflict_entries[2] == NULL ? NULL : &conflict_entries[2]->oid;
|
710
|
+
|
711
|
+
if ((ret = git_index_reuc_add(index, path, ancestor_mode, ancestor_oid,
|
712
|
+
our_mode, our_oid, their_mode, their_oid)) >= 0)
|
713
|
+
ret = git_index_conflict_remove(index, path);
|
714
|
+
|
715
|
+
return ret;
|
527
716
|
}
|
528
717
|
|
529
|
-
int
|
718
|
+
int git_index_add_bypath(git_index *index, const char *path)
|
530
719
|
{
|
531
|
-
|
720
|
+
git_index_entry *entry = NULL;
|
721
|
+
int ret;
|
722
|
+
|
723
|
+
assert(index && path);
|
724
|
+
|
725
|
+
if ((ret = index_entry_init(&entry, index, path)) < 0 ||
|
726
|
+
(ret = index_insert(index, entry, 1)) < 0)
|
727
|
+
goto on_error;
|
728
|
+
|
729
|
+
/* Adding implies conflict was resolved, move conflict entries to REUC */
|
730
|
+
if ((ret = index_conflict_to_reuc(index, path)) < 0 && ret != GIT_ENOTFOUND)
|
731
|
+
goto on_error;
|
732
|
+
|
733
|
+
git_tree_cache_invalidate_path(index->tree, entry->path);
|
734
|
+
return 0;
|
735
|
+
|
736
|
+
on_error:
|
737
|
+
index_entry_free(entry);
|
738
|
+
return ret;
|
532
739
|
}
|
533
740
|
|
534
|
-
int
|
741
|
+
int git_index_remove_bypath(git_index *index, const char *path)
|
535
742
|
{
|
536
|
-
|
743
|
+
int ret;
|
744
|
+
|
745
|
+
assert(index && path);
|
746
|
+
|
747
|
+
if (((ret = git_index_remove(index, path, 0)) < 0 &&
|
748
|
+
ret != GIT_ENOTFOUND) ||
|
749
|
+
((ret = index_conflict_to_reuc(index, path)) < 0 &&
|
750
|
+
ret != GIT_ENOTFOUND))
|
751
|
+
return ret;
|
752
|
+
|
753
|
+
return 0;
|
537
754
|
}
|
538
755
|
|
539
|
-
|
540
|
-
git_index *index, const git_index_entry *source_entry, int replace)
|
756
|
+
int git_index_add(git_index *index, const git_index_entry *source_entry)
|
541
757
|
{
|
542
758
|
git_index_entry *entry = NULL;
|
543
759
|
int ret;
|
@@ -546,7 +762,7 @@ static int index_add2(
|
|
546
762
|
if (entry == NULL)
|
547
763
|
return -1;
|
548
764
|
|
549
|
-
if ((ret = index_insert(index, entry,
|
765
|
+
if ((ret = index_insert(index, entry, 1)) < 0) {
|
550
766
|
index_entry_free(entry);
|
551
767
|
return ret;
|
552
768
|
}
|
@@ -555,28 +771,22 @@ static int index_add2(
|
|
555
771
|
return 0;
|
556
772
|
}
|
557
773
|
|
558
|
-
int
|
559
|
-
{
|
560
|
-
return index_add2(index, source_entry, 1);
|
561
|
-
}
|
562
|
-
|
563
|
-
int git_index_append2(git_index *index, const git_index_entry *source_entry)
|
564
|
-
{
|
565
|
-
return index_add2(index, source_entry, 0);
|
566
|
-
}
|
567
|
-
|
568
|
-
int git_index_remove(git_index *index, int position)
|
774
|
+
int git_index_remove(git_index *index, const char *path, int stage)
|
569
775
|
{
|
776
|
+
size_t position;
|
570
777
|
int error;
|
571
778
|
git_index_entry *entry;
|
572
779
|
|
573
780
|
git_vector_sort(&index->entries);
|
574
781
|
|
782
|
+
if (index_find(&position, index, path, stage) < 0)
|
783
|
+
return GIT_ENOTFOUND;
|
784
|
+
|
575
785
|
entry = git_vector_get(&index->entries, position);
|
576
786
|
if (entry != NULL)
|
577
787
|
git_tree_cache_invalidate_path(index->tree, entry->path);
|
578
788
|
|
579
|
-
error = git_vector_remove(&index->entries,
|
789
|
+
error = git_vector_remove(&index->entries, position);
|
580
790
|
|
581
791
|
if (!error)
|
582
792
|
index_entry_free(entry);
|
@@ -584,45 +794,362 @@ int git_index_remove(git_index *index, int position)
|
|
584
794
|
return error;
|
585
795
|
}
|
586
796
|
|
587
|
-
int
|
797
|
+
int git_index_remove_directory(git_index *index, const char *dir, int stage)
|
798
|
+
{
|
799
|
+
git_buf pfx = GIT_BUF_INIT;
|
800
|
+
int error = 0;
|
801
|
+
size_t pos;
|
802
|
+
git_index_entry *entry;
|
803
|
+
|
804
|
+
if (git_buf_sets(&pfx, dir) < 0 || git_path_to_dir(&pfx) < 0)
|
805
|
+
return -1;
|
806
|
+
|
807
|
+
git_vector_sort(&index->entries);
|
808
|
+
|
809
|
+
pos = git_index__prefix_position(index, pfx.ptr);
|
810
|
+
|
811
|
+
while (1) {
|
812
|
+
entry = git_vector_get(&index->entries, pos);
|
813
|
+
if (!entry || git__prefixcmp(entry->path, pfx.ptr) != 0)
|
814
|
+
break;
|
815
|
+
|
816
|
+
if (index_entry_stage(entry) != stage) {
|
817
|
+
++pos;
|
818
|
+
continue;
|
819
|
+
}
|
820
|
+
|
821
|
+
git_tree_cache_invalidate_path(index->tree, entry->path);
|
822
|
+
|
823
|
+
if ((error = git_vector_remove(&index->entries, pos)) < 0)
|
824
|
+
break;
|
825
|
+
index_entry_free(entry);
|
826
|
+
|
827
|
+
/* removed entry at 'pos' so we don't need to increment it */
|
828
|
+
}
|
829
|
+
|
830
|
+
git_buf_free(&pfx);
|
831
|
+
|
832
|
+
return error;
|
833
|
+
}
|
834
|
+
|
835
|
+
static int index_find(size_t *at_pos, git_index *index, const char *path, int stage)
|
836
|
+
{
|
837
|
+
struct entry_srch_key srch_key;
|
838
|
+
|
839
|
+
assert(path);
|
840
|
+
|
841
|
+
srch_key.path = path;
|
842
|
+
srch_key.stage = stage;
|
843
|
+
|
844
|
+
return git_vector_bsearch2(at_pos, &index->entries, index->entries_search, &srch_key);
|
845
|
+
}
|
846
|
+
|
847
|
+
int git_index_find(size_t *at_pos, git_index *index, const char *path)
|
588
848
|
{
|
589
|
-
|
849
|
+
size_t pos;
|
850
|
+
|
851
|
+
assert(index && path);
|
852
|
+
|
853
|
+
if (git_vector_bsearch2(&pos, &index->entries, index->entries_search_path, path) < 0) {
|
854
|
+
giterr_set(GITERR_INDEX, "Index does not contain %s", path);
|
855
|
+
return GIT_ENOTFOUND;
|
856
|
+
}
|
857
|
+
|
858
|
+
/* Since our binary search only looked at path, we may be in the
|
859
|
+
* middle of a list of stages.
|
860
|
+
*/
|
861
|
+
while (pos > 0) {
|
862
|
+
const git_index_entry *prev = git_vector_get(&index->entries, pos-1);
|
863
|
+
|
864
|
+
if (index->entries_cmp_path(prev->path, path) != 0)
|
865
|
+
break;
|
866
|
+
|
867
|
+
--pos;
|
868
|
+
}
|
869
|
+
|
870
|
+
if (at_pos)
|
871
|
+
*at_pos = pos;
|
872
|
+
|
873
|
+
return 0;
|
590
874
|
}
|
591
875
|
|
592
|
-
|
876
|
+
size_t git_index__prefix_position(git_index *index, const char *path)
|
593
877
|
{
|
594
|
-
|
878
|
+
struct entry_srch_key srch_key;
|
879
|
+
size_t pos;
|
880
|
+
|
881
|
+
srch_key.path = path;
|
882
|
+
srch_key.stage = 0;
|
595
883
|
|
596
|
-
|
884
|
+
git_vector_sort(&index->entries);
|
885
|
+
git_vector_bsearch2(
|
886
|
+
&pos, &index->entries, index->entries_search, &srch_key);
|
597
887
|
|
598
888
|
return pos;
|
599
889
|
}
|
600
890
|
|
601
|
-
|
891
|
+
int git_index_conflict_add(git_index *index,
|
892
|
+
const git_index_entry *ancestor_entry,
|
893
|
+
const git_index_entry *our_entry,
|
894
|
+
const git_index_entry *their_entry)
|
895
|
+
{
|
896
|
+
git_index_entry *entries[3] = { 0 };
|
897
|
+
unsigned short i;
|
898
|
+
int ret = 0;
|
899
|
+
|
900
|
+
assert (index);
|
901
|
+
|
902
|
+
if ((ancestor_entry != NULL && (entries[0] = index_entry_dup(ancestor_entry)) == NULL) ||
|
903
|
+
(our_entry != NULL && (entries[1] = index_entry_dup(our_entry)) == NULL) ||
|
904
|
+
(their_entry != NULL && (entries[2] = index_entry_dup(their_entry)) == NULL))
|
905
|
+
return -1;
|
906
|
+
|
907
|
+
for (i = 0; i < 3; i++) {
|
908
|
+
if (entries[i] == NULL)
|
909
|
+
continue;
|
910
|
+
|
911
|
+
/* Make sure stage is correct */
|
912
|
+
entries[i]->flags = (entries[i]->flags & ~GIT_IDXENTRY_STAGEMASK) |
|
913
|
+
((i+1) << GIT_IDXENTRY_STAGESHIFT);
|
914
|
+
|
915
|
+
if ((ret = index_insert(index, entries[i], 1)) < 0)
|
916
|
+
goto on_error;
|
917
|
+
}
|
918
|
+
|
919
|
+
return 0;
|
920
|
+
|
921
|
+
on_error:
|
922
|
+
for (i = 0; i < 3; i++) {
|
923
|
+
if (entries[i] != NULL)
|
924
|
+
index_entry_free(entries[i]);
|
925
|
+
}
|
926
|
+
|
927
|
+
return ret;
|
928
|
+
}
|
929
|
+
|
930
|
+
int git_index_conflict_get(git_index_entry **ancestor_out,
|
931
|
+
git_index_entry **our_out,
|
932
|
+
git_index_entry **their_out,
|
933
|
+
git_index *index, const char *path)
|
934
|
+
{
|
935
|
+
size_t pos, posmax;
|
936
|
+
int stage;
|
937
|
+
git_index_entry *conflict_entry;
|
938
|
+
int error = GIT_ENOTFOUND;
|
939
|
+
|
940
|
+
assert(ancestor_out && our_out && their_out && index && path);
|
941
|
+
|
942
|
+
*ancestor_out = NULL;
|
943
|
+
*our_out = NULL;
|
944
|
+
*their_out = NULL;
|
945
|
+
|
946
|
+
if (git_index_find(&pos, index, path) < 0)
|
947
|
+
return GIT_ENOTFOUND;
|
948
|
+
|
949
|
+
for (posmax = git_index_entrycount(index); pos < posmax; ++pos) {
|
950
|
+
|
951
|
+
conflict_entry = git_vector_get(&index->entries, pos);
|
952
|
+
|
953
|
+
if (index->entries_cmp_path(conflict_entry->path, path) != 0)
|
954
|
+
break;
|
955
|
+
|
956
|
+
stage = index_entry_stage(conflict_entry);
|
957
|
+
|
958
|
+
switch (stage) {
|
959
|
+
case 3:
|
960
|
+
*their_out = conflict_entry;
|
961
|
+
error = 0;
|
962
|
+
break;
|
963
|
+
case 2:
|
964
|
+
*our_out = conflict_entry;
|
965
|
+
error = 0;
|
966
|
+
break;
|
967
|
+
case 1:
|
968
|
+
*ancestor_out = conflict_entry;
|
969
|
+
error = 0;
|
970
|
+
break;
|
971
|
+
default:
|
972
|
+
break;
|
973
|
+
};
|
974
|
+
}
|
975
|
+
|
976
|
+
return error;
|
977
|
+
}
|
978
|
+
|
979
|
+
int git_index_conflict_remove(git_index *index, const char *path)
|
980
|
+
{
|
981
|
+
size_t pos, posmax;
|
982
|
+
git_index_entry *conflict_entry;
|
983
|
+
int error = 0;
|
984
|
+
|
985
|
+
assert(index && path);
|
986
|
+
|
987
|
+
if (git_index_find(&pos, index, path) < 0)
|
988
|
+
return GIT_ENOTFOUND;
|
989
|
+
|
990
|
+
posmax = git_index_entrycount(index);
|
991
|
+
|
992
|
+
while (pos < posmax) {
|
993
|
+
conflict_entry = git_vector_get(&index->entries, pos);
|
994
|
+
|
995
|
+
if (index->entries_cmp_path(conflict_entry->path, path) != 0)
|
996
|
+
break;
|
997
|
+
|
998
|
+
if (index_entry_stage(conflict_entry) == 0) {
|
999
|
+
pos++;
|
1000
|
+
continue;
|
1001
|
+
}
|
1002
|
+
|
1003
|
+
if ((error = git_vector_remove(&index->entries, pos)) < 0)
|
1004
|
+
return error;
|
1005
|
+
|
1006
|
+
index_entry_free(conflict_entry);
|
1007
|
+
posmax--;
|
1008
|
+
}
|
1009
|
+
|
1010
|
+
return 0;
|
1011
|
+
}
|
1012
|
+
|
1013
|
+
static int index_conflicts_match(const git_vector *v, size_t idx)
|
1014
|
+
{
|
1015
|
+
git_index_entry *entry = git_vector_get(v, idx);
|
1016
|
+
|
1017
|
+
if (index_entry_stage(entry) > 0) {
|
1018
|
+
index_entry_free(entry);
|
1019
|
+
return 1;
|
1020
|
+
}
|
1021
|
+
|
1022
|
+
return 0;
|
1023
|
+
}
|
1024
|
+
|
1025
|
+
void git_index_conflict_cleanup(git_index *index)
|
1026
|
+
{
|
1027
|
+
assert(index);
|
1028
|
+
git_vector_remove_matching(&index->entries, index_conflicts_match);
|
1029
|
+
}
|
1030
|
+
|
1031
|
+
int git_index_has_conflicts(const git_index *index)
|
1032
|
+
{
|
1033
|
+
size_t i;
|
1034
|
+
git_index_entry *entry;
|
1035
|
+
|
1036
|
+
assert(index);
|
1037
|
+
|
1038
|
+
git_vector_foreach(&index->entries, i, entry) {
|
1039
|
+
if (index_entry_stage(entry) > 0)
|
1040
|
+
return 1;
|
1041
|
+
}
|
1042
|
+
|
1043
|
+
return 0;
|
1044
|
+
}
|
1045
|
+
|
1046
|
+
unsigned int git_index_reuc_entrycount(git_index *index)
|
1047
|
+
{
|
1048
|
+
assert(index);
|
1049
|
+
return (unsigned int)index->reuc.length;
|
1050
|
+
}
|
1051
|
+
|
1052
|
+
static int index_reuc_insert(git_index *index, git_index_reuc_entry *reuc, int replace)
|
602
1053
|
{
|
603
|
-
|
1054
|
+
git_index_reuc_entry **existing = NULL;
|
1055
|
+
size_t position;
|
1056
|
+
|
1057
|
+
assert(index && reuc && reuc->path != NULL);
|
1058
|
+
|
1059
|
+
if (!git_index_reuc_find(&position, index, reuc->path))
|
1060
|
+
existing = (git_index_reuc_entry **)&index->reuc.contents[position];
|
1061
|
+
|
1062
|
+
if (!replace || !existing)
|
1063
|
+
return git_vector_insert(&index->reuc, reuc);
|
1064
|
+
|
1065
|
+
/* exists, replace it */
|
1066
|
+
git__free((*existing)->path);
|
1067
|
+
git__free(*existing);
|
1068
|
+
*existing = reuc;
|
1069
|
+
|
1070
|
+
return 0;
|
604
1071
|
}
|
605
1072
|
|
606
|
-
const
|
1073
|
+
int git_index_reuc_add(git_index *index, const char *path,
|
1074
|
+
int ancestor_mode, git_oid *ancestor_oid,
|
1075
|
+
int our_mode, git_oid *our_oid,
|
1076
|
+
int their_mode, git_oid *their_oid)
|
1077
|
+
{
|
1078
|
+
git_index_reuc_entry *reuc = NULL;
|
1079
|
+
int error = 0;
|
1080
|
+
|
1081
|
+
assert(index && path);
|
1082
|
+
|
1083
|
+
if ((error = index_entry_reuc_init(&reuc, path, ancestor_mode, ancestor_oid, our_mode, our_oid, their_mode, their_oid)) < 0 ||
|
1084
|
+
(error = index_reuc_insert(index, reuc, 1)) < 0)
|
1085
|
+
{
|
1086
|
+
index_entry_reuc_free(reuc);
|
1087
|
+
return error;
|
1088
|
+
}
|
1089
|
+
|
1090
|
+
return error;
|
1091
|
+
}
|
1092
|
+
|
1093
|
+
int git_index_reuc_find(size_t *at_pos, git_index *index, const char *path)
|
1094
|
+
{
|
1095
|
+
return git_vector_bsearch2(at_pos, &index->reuc, index->reuc_search, path);
|
1096
|
+
}
|
1097
|
+
|
1098
|
+
const git_index_reuc_entry *git_index_reuc_get_bypath(
|
607
1099
|
git_index *index, const char *path)
|
608
1100
|
{
|
609
|
-
|
1101
|
+
size_t pos;
|
610
1102
|
assert(index && path);
|
611
1103
|
|
612
|
-
if (!index->
|
1104
|
+
if (!index->reuc.length)
|
613
1105
|
return NULL;
|
614
1106
|
|
615
|
-
|
1107
|
+
git_vector_sort(&index->reuc);
|
1108
|
+
|
1109
|
+
if (git_index_reuc_find(&pos, index, path) < 0)
|
616
1110
|
return NULL;
|
617
1111
|
|
618
|
-
return git_vector_get(&index->
|
1112
|
+
return git_vector_get(&index->reuc, pos);
|
619
1113
|
}
|
620
1114
|
|
621
|
-
const
|
1115
|
+
const git_index_reuc_entry *git_index_reuc_get_byindex(
|
622
1116
|
git_index *index, size_t n)
|
623
1117
|
{
|
624
1118
|
assert(index);
|
625
|
-
|
1119
|
+
|
1120
|
+
git_vector_sort(&index->reuc);
|
1121
|
+
return git_vector_get(&index->reuc, n);
|
1122
|
+
}
|
1123
|
+
|
1124
|
+
int git_index_reuc_remove(git_index *index, size_t position)
|
1125
|
+
{
|
1126
|
+
int error;
|
1127
|
+
git_index_reuc_entry *reuc;
|
1128
|
+
|
1129
|
+
git_vector_sort(&index->reuc);
|
1130
|
+
|
1131
|
+
reuc = git_vector_get(&index->reuc, position);
|
1132
|
+
error = git_vector_remove(&index->reuc, position);
|
1133
|
+
|
1134
|
+
if (!error)
|
1135
|
+
index_entry_reuc_free(reuc);
|
1136
|
+
|
1137
|
+
return error;
|
1138
|
+
}
|
1139
|
+
|
1140
|
+
void git_index_reuc_clear(git_index *index)
|
1141
|
+
{
|
1142
|
+
size_t i;
|
1143
|
+
git_index_reuc_entry *reuc;
|
1144
|
+
|
1145
|
+
assert(index);
|
1146
|
+
|
1147
|
+
git_vector_foreach(&index->reuc, i, reuc) {
|
1148
|
+
git__free(reuc->path);
|
1149
|
+
git__free(reuc);
|
1150
|
+
}
|
1151
|
+
|
1152
|
+
git_vector_clear(&index->reuc);
|
626
1153
|
}
|
627
1154
|
|
628
1155
|
static int index_error_invalid(const char *message)
|
@@ -631,26 +1158,27 @@ static int index_error_invalid(const char *message)
|
|
631
1158
|
return -1;
|
632
1159
|
}
|
633
1160
|
|
634
|
-
static int
|
1161
|
+
static int read_reuc(git_index *index, const char *buffer, size_t size)
|
635
1162
|
{
|
636
1163
|
const char *endptr;
|
637
1164
|
size_t len;
|
638
1165
|
int i;
|
639
1166
|
|
640
|
-
|
1167
|
+
/* This gets called multiple times, the vector might already be initialized */
|
1168
|
+
if (index->reuc._alloc_size == 0 && git_vector_init(&index->reuc, 16, reuc_cmp) < 0)
|
641
1169
|
return -1;
|
642
1170
|
|
643
1171
|
while (size) {
|
644
|
-
|
1172
|
+
git_index_reuc_entry *lost;
|
645
1173
|
|
646
1174
|
len = strlen(buffer) + 1;
|
647
1175
|
if (size <= len)
|
648
|
-
return index_error_invalid("reading
|
1176
|
+
return index_error_invalid("reading reuc entries");
|
649
1177
|
|
650
|
-
lost = git__malloc(sizeof(
|
1178
|
+
lost = git__malloc(sizeof(git_index_reuc_entry));
|
651
1179
|
GITERR_CHECK_ALLOC(lost);
|
652
1180
|
|
653
|
-
if (git_vector_insert(&index->
|
1181
|
+
if (git_vector_insert(&index->reuc, lost) < 0)
|
654
1182
|
return -1;
|
655
1183
|
|
656
1184
|
/* read NUL-terminated pathname for entry */
|
@@ -667,13 +1195,13 @@ static int read_unmerged(git_index *index, const char *buffer, size_t size)
|
|
667
1195
|
if (git__strtol32(&tmp, buffer, &endptr, 8) < 0 ||
|
668
1196
|
!endptr || endptr == buffer || *endptr ||
|
669
1197
|
(unsigned)tmp > UINT_MAX)
|
670
|
-
return index_error_invalid("reading
|
1198
|
+
return index_error_invalid("reading reuc entry stage");
|
671
1199
|
|
672
1200
|
lost->mode[i] = tmp;
|
673
1201
|
|
674
1202
|
len = (endptr + 1) - buffer;
|
675
1203
|
if (size <= len)
|
676
|
-
return index_error_invalid("reading
|
1204
|
+
return index_error_invalid("reading reuc entry stage");
|
677
1205
|
|
678
1206
|
size -= len;
|
679
1207
|
buffer += len;
|
@@ -684,7 +1212,7 @@ static int read_unmerged(git_index *index, const char *buffer, size_t size)
|
|
684
1212
|
if (!lost->mode[i])
|
685
1213
|
continue;
|
686
1214
|
if (size < 20)
|
687
|
-
return index_error_invalid("reading
|
1215
|
+
return index_error_invalid("reading reuc entry oid");
|
688
1216
|
|
689
1217
|
git_oid_fromraw(&lost->oid[i], (const unsigned char *) buffer);
|
690
1218
|
size -= 20;
|
@@ -692,6 +1220,9 @@ static int read_unmerged(git_index *index, const char *buffer, size_t size)
|
|
692
1220
|
}
|
693
1221
|
}
|
694
1222
|
|
1223
|
+
/* entries are guaranteed to be sorted on-disk */
|
1224
|
+
index->reuc.sorted = 1;
|
1225
|
+
|
695
1226
|
return 0;
|
696
1227
|
}
|
697
1228
|
|
@@ -797,7 +1328,7 @@ static size_t read_extension(git_index *index, const char *buffer, size_t buffer
|
|
797
1328
|
if (git_tree_cache_read(&index->tree, buffer + 8, dest.extension_size) < 0)
|
798
1329
|
return 0;
|
799
1330
|
} else if (memcmp(dest.signature, INDEX_EXT_UNMERGED_SIG, 4) == 0) {
|
800
|
-
if (
|
1331
|
+
if (read_reuc(index, buffer + 8, dest.extension_size) < 0)
|
801
1332
|
return 0;
|
802
1333
|
}
|
803
1334
|
/* else, unsupported extension. We cannot parse this, but we can skip
|
@@ -886,15 +1417,16 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
|
|
886
1417
|
|
887
1418
|
#undef seek_forward
|
888
1419
|
|
889
|
-
/*
|
890
|
-
|
891
|
-
index->entries
|
1420
|
+
/* Entries are stored case-sensitively on disk. */
|
1421
|
+
index->entries.sorted = !index->ignore_case;
|
1422
|
+
git_vector_sort(&index->entries);
|
1423
|
+
|
892
1424
|
return 0;
|
893
1425
|
}
|
894
1426
|
|
895
|
-
static
|
1427
|
+
static bool is_index_extended(git_index *index)
|
896
1428
|
{
|
897
|
-
|
1429
|
+
size_t i, extended;
|
898
1430
|
git_index_entry *entry;
|
899
1431
|
|
900
1432
|
extended = 0;
|
@@ -907,7 +1439,7 @@ static int is_index_extended(git_index *index)
|
|
907
1439
|
}
|
908
1440
|
}
|
909
1441
|
|
910
|
-
return extended;
|
1442
|
+
return (extended > 0);
|
911
1443
|
}
|
912
1444
|
|
913
1445
|
static int write_disk_entry(git_filebuf *file, git_index_entry *entry)
|
@@ -973,7 +1505,7 @@ static int write_disk_entry(git_filebuf *file, git_index_entry *entry)
|
|
973
1505
|
static int write_entries(git_index *index, git_filebuf *file)
|
974
1506
|
{
|
975
1507
|
int error = 0;
|
976
|
-
|
1508
|
+
size_t i;
|
977
1509
|
git_vector case_sorted;
|
978
1510
|
git_index_entry *entry;
|
979
1511
|
git_vector *out = &index->entries;
|
@@ -996,13 +1528,74 @@ static int write_entries(git_index *index, git_filebuf *file)
|
|
996
1528
|
return error;
|
997
1529
|
}
|
998
1530
|
|
1531
|
+
static int write_extension(git_filebuf *file, struct index_extension *header, git_buf *data)
|
1532
|
+
{
|
1533
|
+
struct index_extension ondisk;
|
1534
|
+
int error = 0;
|
1535
|
+
|
1536
|
+
memset(&ondisk, 0x0, sizeof(struct index_extension));
|
1537
|
+
memcpy(&ondisk, header, 4);
|
1538
|
+
ondisk.extension_size = htonl(header->extension_size);
|
1539
|
+
|
1540
|
+
if ((error = git_filebuf_write(file, &ondisk, sizeof(struct index_extension))) == 0)
|
1541
|
+
error = git_filebuf_write(file, data->ptr, data->size);
|
1542
|
+
|
1543
|
+
return error;
|
1544
|
+
}
|
1545
|
+
|
1546
|
+
static int create_reuc_extension_data(git_buf *reuc_buf, git_index_reuc_entry *reuc)
|
1547
|
+
{
|
1548
|
+
int i;
|
1549
|
+
int error = 0;
|
1550
|
+
|
1551
|
+
if ((error = git_buf_put(reuc_buf, reuc->path, strlen(reuc->path) + 1)) < 0)
|
1552
|
+
return error;
|
1553
|
+
|
1554
|
+
for (i = 0; i < 3; i++) {
|
1555
|
+
if ((error = git_buf_printf(reuc_buf, "%o", reuc->mode[i])) < 0 ||
|
1556
|
+
(error = git_buf_put(reuc_buf, "\0", 1)) < 0)
|
1557
|
+
return error;
|
1558
|
+
}
|
1559
|
+
|
1560
|
+
for (i = 0; i < 3; i++) {
|
1561
|
+
if (reuc->mode[i] && (error = git_buf_put(reuc_buf, (char *)&reuc->oid[i].id, GIT_OID_RAWSZ)) < 0)
|
1562
|
+
return error;
|
1563
|
+
}
|
1564
|
+
|
1565
|
+
return 0;
|
1566
|
+
}
|
1567
|
+
|
1568
|
+
static int write_reuc_extension(git_index *index, git_filebuf *file)
|
1569
|
+
{
|
1570
|
+
git_buf reuc_buf = GIT_BUF_INIT;
|
1571
|
+
git_vector *out = &index->reuc;
|
1572
|
+
git_index_reuc_entry *reuc;
|
1573
|
+
struct index_extension extension;
|
1574
|
+
size_t i;
|
1575
|
+
int error = 0;
|
1576
|
+
|
1577
|
+
git_vector_foreach(out, i, reuc) {
|
1578
|
+
if ((error = create_reuc_extension_data(&reuc_buf, reuc)) < 0)
|
1579
|
+
goto done;
|
1580
|
+
}
|
1581
|
+
|
1582
|
+
memset(&extension, 0x0, sizeof(struct index_extension));
|
1583
|
+
memcpy(&extension.signature, INDEX_EXT_UNMERGED_SIG, 4);
|
1584
|
+
extension.extension_size = (uint32_t)reuc_buf.size;
|
1585
|
+
|
1586
|
+
error = write_extension(file, &extension, &reuc_buf);
|
1587
|
+
|
1588
|
+
git_buf_free(&reuc_buf);
|
1589
|
+
|
1590
|
+
done:
|
1591
|
+
return error;
|
1592
|
+
}
|
1593
|
+
|
999
1594
|
static int write_index(git_index *index, git_filebuf *file)
|
1000
1595
|
{
|
1001
1596
|
git_oid hash_final;
|
1002
|
-
|
1003
1597
|
struct index_header header;
|
1004
|
-
|
1005
|
-
int is_extended;
|
1598
|
+
bool is_extended;
|
1006
1599
|
|
1007
1600
|
assert(index && file);
|
1008
1601
|
|
@@ -1018,7 +1611,11 @@ static int write_index(git_index *index, git_filebuf *file)
|
|
1018
1611
|
if (write_entries(index, file) < 0)
|
1019
1612
|
return -1;
|
1020
1613
|
|
1021
|
-
/* TODO: write
|
1614
|
+
/* TODO: write tree cache extension */
|
1615
|
+
|
1616
|
+
/* write the reuc extension */
|
1617
|
+
if (index->reuc.length > 0 && write_reuc_extension(index, file) < 0)
|
1618
|
+
return -1;
|
1022
1619
|
|
1023
1620
|
/* get out the hash for all the contents we've appended to the file */
|
1024
1621
|
git_filebuf_hash(&hash_final, file);
|
@@ -1029,22 +1626,20 @@ static int write_index(git_index *index, git_filebuf *file)
|
|
1029
1626
|
|
1030
1627
|
int git_index_entry_stage(const git_index_entry *entry)
|
1031
1628
|
{
|
1032
|
-
return (entry
|
1629
|
+
return index_entry_stage(entry);
|
1033
1630
|
}
|
1034
1631
|
|
1035
1632
|
typedef struct read_tree_data {
|
1036
1633
|
git_index *index;
|
1037
|
-
|
1634
|
+
git_transfer_progress *stats;
|
1038
1635
|
} read_tree_data;
|
1039
1636
|
|
1040
1637
|
static int read_tree_cb(const char *root, const git_tree_entry *tentry, void *data)
|
1041
1638
|
{
|
1042
|
-
|
1639
|
+
git_index *index = (git_index *)data;
|
1043
1640
|
git_index_entry *entry = NULL;
|
1044
1641
|
git_buf path = GIT_BUF_INIT;
|
1045
1642
|
|
1046
|
-
rtd->stats->total++;
|
1047
|
-
|
1048
1643
|
if (git_tree_entry__is_tree(tentry))
|
1049
1644
|
return 0;
|
1050
1645
|
|
@@ -1056,10 +1651,16 @@ static int read_tree_cb(const char *root, const git_tree_entry *tentry, void *da
|
|
1056
1651
|
|
1057
1652
|
entry->mode = tentry->attr;
|
1058
1653
|
entry->oid = tentry->oid;
|
1654
|
+
|
1655
|
+
if (path.size < GIT_IDXENTRY_NAMEMASK)
|
1656
|
+
entry->flags = path.size & GIT_IDXENTRY_NAMEMASK;
|
1657
|
+
else
|
1658
|
+
entry->flags = GIT_IDXENTRY_NAMEMASK;
|
1659
|
+
|
1059
1660
|
entry->path = git_buf_detach(&path);
|
1060
1661
|
git_buf_free(&path);
|
1061
1662
|
|
1062
|
-
if (
|
1663
|
+
if (git_vector_insert(&index->entries, entry) < 0) {
|
1063
1664
|
index_entry_free(entry);
|
1064
1665
|
return -1;
|
1065
1666
|
}
|
@@ -1067,16 +1668,14 @@ static int read_tree_cb(const char *root, const git_tree_entry *tentry, void *da
|
|
1067
1668
|
return 0;
|
1068
1669
|
}
|
1069
1670
|
|
1070
|
-
int git_index_read_tree(git_index *index, git_tree *tree
|
1671
|
+
int git_index_read_tree(git_index *index, const git_tree *tree)
|
1071
1672
|
{
|
1072
|
-
git_indexer_stats dummy_stats;
|
1073
|
-
read_tree_data rtd = {index, NULL};
|
1074
|
-
|
1075
|
-
if (!stats) stats = &dummy_stats;
|
1076
|
-
stats->total = 0;
|
1077
|
-
rtd.stats = stats;
|
1078
|
-
|
1079
1673
|
git_index_clear(index);
|
1080
1674
|
|
1081
|
-
return git_tree_walk(tree,
|
1675
|
+
return git_tree_walk(tree, GIT_TREEWALK_POST, read_tree_cb, index);
|
1676
|
+
}
|
1677
|
+
|
1678
|
+
git_repository *git_index_owner(const git_index *index)
|
1679
|
+
{
|
1680
|
+
return INDEX_OWNER(index);
|
1082
1681
|
}
|