rugged 0.17.0.b6 → 0.17.0.b7
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +3 -3
- data/Rakefile +3 -1
- data/ext/rugged/rugged.c +30 -0
- data/ext/rugged/rugged.h +9 -0
- data/ext/rugged/rugged_branch.c +306 -0
- data/ext/rugged/rugged_config.c +16 -13
- data/ext/rugged/rugged_index.c +25 -0
- data/ext/rugged/rugged_object.c +6 -2
- data/ext/rugged/rugged_reference.c +11 -18
- data/ext/rugged/rugged_revwalk.c +1 -1
- data/lib/rugged.rb +1 -0
- data/lib/rugged/branch.rb +28 -0
- data/lib/rugged/commit.rb +5 -5
- data/lib/rugged/repository.rb +32 -7
- data/lib/rugged/tag.rb +5 -1
- data/lib/rugged/version.rb +1 -1
- data/test/branch_test.rb +227 -0
- data/test/config_test.rb +1 -1
- data/test/fixtures/testrepo.git/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 +0 -0
- data/test/fixtures/testrepo.git/objects/a3/e05719b428a2d0ed7a55c4ce53dcc5768c6d5e +0 -0
- data/test/index_test.rb +31 -0
- data/test/index_test.rb~ +218 -0
- data/test/lib_test.rb +22 -0
- data/test/reference_test.rb +5 -3
- data/vendor/libgit2/Makefile.embed +1 -1
- data/vendor/libgit2/include/git2.h +1 -0
- data/vendor/libgit2/include/git2/branch.h +17 -13
- data/vendor/libgit2/include/git2/checkout.h +83 -22
- data/vendor/libgit2/include/git2/clone.h +6 -3
- data/vendor/libgit2/include/git2/common.h +1 -8
- data/vendor/libgit2/include/git2/config.h +185 -26
- data/vendor/libgit2/include/git2/diff.h +229 -17
- data/vendor/libgit2/include/git2/errors.h +39 -1
- data/vendor/libgit2/include/git2/ignore.h +6 -3
- data/vendor/libgit2/include/git2/indexer.h +1 -0
- data/vendor/libgit2/include/git2/merge.h +1 -1
- data/vendor/libgit2/include/git2/object.h +7 -4
- data/vendor/libgit2/include/git2/odb.h +4 -2
- data/vendor/libgit2/include/git2/odb_backend.h +6 -0
- data/vendor/libgit2/include/git2/oid.h +2 -0
- data/vendor/libgit2/include/git2/pack.h +89 -0
- data/vendor/libgit2/include/git2/refs.h +88 -0
- data/vendor/libgit2/include/git2/refspec.h +0 -8
- data/vendor/libgit2/include/git2/remote.h +34 -1
- data/vendor/libgit2/include/git2/repository.h +238 -6
- data/vendor/libgit2/include/git2/reset.h +4 -1
- data/vendor/libgit2/include/git2/revwalk.h +1 -1
- data/vendor/libgit2/include/git2/status.h +19 -14
- data/vendor/libgit2/include/git2/strarray.h +54 -0
- data/vendor/libgit2/include/git2/submodule.h +451 -45
- data/vendor/libgit2/include/git2/tag.h +16 -0
- data/vendor/libgit2/include/git2/tree.h +2 -2
- data/vendor/libgit2/include/git2/types.h +4 -0
- data/vendor/libgit2/src/amiga/map.c +4 -7
- data/vendor/libgit2/src/attr.c +21 -13
- data/vendor/libgit2/src/attr.h +3 -1
- data/vendor/libgit2/src/attr_file.c +14 -14
- data/vendor/libgit2/src/attr_file.h +6 -5
- data/vendor/libgit2/src/blob.c +22 -12
- data/vendor/libgit2/src/branch.c +62 -66
- data/vendor/libgit2/src/buffer.c +63 -14
- data/vendor/libgit2/src/buffer.h +4 -0
- data/vendor/libgit2/src/cache.c +5 -4
- data/vendor/libgit2/src/checkout.c +381 -159
- data/vendor/libgit2/src/clone.c +221 -94
- data/vendor/libgit2/src/common.h +13 -3
- data/vendor/libgit2/src/compress.c +53 -0
- data/vendor/libgit2/src/compress.h +16 -0
- data/vendor/libgit2/src/config.c +380 -175
- data/vendor/libgit2/src/config.h +2 -5
- data/vendor/libgit2/src/config_file.c +63 -46
- data/vendor/libgit2/src/config_file.h +16 -4
- data/vendor/libgit2/src/crlf.c +4 -3
- data/vendor/libgit2/src/delta.c +491 -0
- data/vendor/libgit2/src/delta.h +112 -0
- data/vendor/libgit2/src/diff.c +310 -67
- data/vendor/libgit2/src/diff.h +10 -1
- data/vendor/libgit2/src/diff_output.c +1030 -337
- data/vendor/libgit2/src/diff_output.h +86 -0
- data/vendor/libgit2/src/errors.c +10 -1
- data/vendor/libgit2/src/fetch.c +108 -24
- data/vendor/libgit2/src/filebuf.c +8 -2
- data/vendor/libgit2/src/fileops.c +342 -177
- data/vendor/libgit2/src/fileops.h +84 -7
- data/vendor/libgit2/src/filter.c +0 -35
- data/vendor/libgit2/src/filter.h +0 -12
- data/vendor/libgit2/src/{compat/fnmatch.c → fnmatch.c} +16 -4
- data/vendor/libgit2/src/{compat/fnmatch.h → fnmatch.h} +4 -3
- data/vendor/libgit2/src/global.c +4 -0
- data/vendor/libgit2/src/ignore.c +122 -23
- data/vendor/libgit2/src/ignore.h +1 -0
- data/vendor/libgit2/src/index.c +56 -10
- data/vendor/libgit2/src/index.h +2 -0
- data/vendor/libgit2/src/indexer.c +8 -9
- data/vendor/libgit2/src/iterator.c +244 -31
- data/vendor/libgit2/src/iterator.h +30 -1
- data/vendor/libgit2/src/message.c +1 -1
- data/vendor/libgit2/src/netops.c +44 -4
- data/vendor/libgit2/src/object.c +80 -69
- data/vendor/libgit2/src/object.h +39 -0
- data/vendor/libgit2/src/odb.c +79 -15
- data/vendor/libgit2/src/odb.h +20 -5
- data/vendor/libgit2/src/odb_pack.c +65 -33
- data/vendor/libgit2/src/oid.c +0 -3
- data/vendor/libgit2/src/pack-objects.c +1315 -0
- data/vendor/libgit2/src/pack-objects.h +87 -0
- data/vendor/libgit2/src/pack.c +36 -12
- data/vendor/libgit2/src/pack.h +1 -0
- data/vendor/libgit2/src/path.c +42 -9
- data/vendor/libgit2/src/path.h +14 -0
- data/vendor/libgit2/src/pkt.c +52 -2
- data/vendor/libgit2/src/pkt.h +10 -0
- data/vendor/libgit2/src/pool.h +11 -0
- data/vendor/libgit2/src/posix.h +8 -0
- data/vendor/libgit2/src/protocol.c +24 -2
- data/vendor/libgit2/src/protocol.h +4 -0
- data/vendor/libgit2/src/reflog.c +1 -1
- data/vendor/libgit2/src/refs.c +292 -124
- data/vendor/libgit2/src/refs.h +4 -2
- data/vendor/libgit2/src/refspec.c +117 -19
- data/vendor/libgit2/src/refspec.h +19 -0
- data/vendor/libgit2/src/remote.c +152 -48
- data/vendor/libgit2/src/remote.h +4 -1
- data/vendor/libgit2/src/repo_template.h +58 -0
- data/vendor/libgit2/src/repository.c +594 -179
- data/vendor/libgit2/src/repository.h +23 -22
- data/vendor/libgit2/src/reset.c +71 -29
- data/vendor/libgit2/src/revparse.c +26 -17
- data/vendor/libgit2/src/revwalk.c +36 -19
- data/vendor/libgit2/src/sha1.h +7 -0
- data/vendor/libgit2/src/{sha1.c → sha1/sha1.c} +0 -0
- data/vendor/libgit2/src/signature.c +12 -10
- data/vendor/libgit2/src/status.c +52 -6
- data/vendor/libgit2/src/submodule.c +1363 -255
- data/vendor/libgit2/src/submodule.h +102 -0
- data/vendor/libgit2/src/tag.c +42 -26
- data/vendor/libgit2/src/thread-utils.h +7 -7
- data/vendor/libgit2/src/transport.h +15 -1
- data/vendor/libgit2/src/transports/git.c +1 -1
- data/vendor/libgit2/src/transports/http.c +197 -36
- data/vendor/libgit2/src/tree.c +3 -3
- data/vendor/libgit2/src/unix/map.c +2 -0
- data/vendor/libgit2/src/unix/posix.h +1 -8
- data/vendor/libgit2/src/util.c +6 -1
- data/vendor/libgit2/src/util.h +7 -0
- data/vendor/libgit2/src/vector.c +16 -0
- data/vendor/libgit2/src/vector.h +1 -0
- data/vendor/libgit2/src/win32/dir.c +8 -21
- data/vendor/libgit2/src/win32/findfile.c +149 -0
- data/vendor/libgit2/src/win32/findfile.h +23 -0
- data/vendor/libgit2/src/win32/posix.h +3 -7
- data/vendor/libgit2/src/win32/posix_w32.c +44 -102
- data/vendor/libgit2/src/win32/pthread.c +68 -0
- data/vendor/libgit2/src/win32/pthread.h +7 -0
- data/vendor/libgit2/src/win32/utf-conv.c +60 -71
- data/vendor/libgit2/src/win32/utf-conv.h +4 -3
- metadata +70 -71
- data/vendor/libgit2/include/git2/windows.h +0 -59
@@ -19,6 +19,7 @@
|
|
19
19
|
*/
|
20
20
|
extern int git_futils_readbuffer(git_buf *obj, const char *path);
|
21
21
|
extern int git_futils_readbuffer_updated(git_buf *obj, const char *path, time_t *mtime, int *updated);
|
22
|
+
extern int git_futils_readbuffer_fd(git_buf *obj, git_file fd, size_t len);
|
22
23
|
|
23
24
|
/**
|
24
25
|
* File utils
|
@@ -50,11 +51,46 @@ extern int git_futils_creat_locked_withpath(const char *path, const mode_t dirmo
|
|
50
51
|
/**
|
51
52
|
* Create a path recursively
|
52
53
|
*
|
53
|
-
* If a base parameter is being passed, it's expected to be valued with a
|
54
|
-
*
|
54
|
+
* If a base parameter is being passed, it's expected to be valued with a
|
55
|
+
* path pointing to an already existing directory.
|
55
56
|
*/
|
56
57
|
extern int git_futils_mkdir_r(const char *path, const char *base, const mode_t mode);
|
57
58
|
|
59
|
+
/**
|
60
|
+
* Flags to pass to `git_futils_mkdir`.
|
61
|
+
*
|
62
|
+
* * GIT_MKDIR_EXCL is "exclusive" - i.e. generate an error if dir exists.
|
63
|
+
* * GIT_MKDIR_PATH says to make all components in the path.
|
64
|
+
* * GIT_MKDIR_CHMOD says to chmod the final directory entry after creation
|
65
|
+
* * GIT_MKDIR_CHMOD_PATH says to chmod each directory component in the path
|
66
|
+
* * GIT_MKDIR_SKIP_LAST says to leave off the last element of the path
|
67
|
+
*
|
68
|
+
* Note that the chmod options will be executed even if the directory already
|
69
|
+
* exists, unless GIT_MKDIR_EXCL is given.
|
70
|
+
*/
|
71
|
+
typedef enum {
|
72
|
+
GIT_MKDIR_EXCL = 1,
|
73
|
+
GIT_MKDIR_PATH = 2,
|
74
|
+
GIT_MKDIR_CHMOD = 4,
|
75
|
+
GIT_MKDIR_CHMOD_PATH = 8,
|
76
|
+
GIT_MKDIR_SKIP_LAST = 16
|
77
|
+
} git_futils_mkdir_flags;
|
78
|
+
|
79
|
+
/**
|
80
|
+
* Create a directory or entire path.
|
81
|
+
*
|
82
|
+
* This makes a directory (and the entire path leading up to it if requested),
|
83
|
+
* and optionally chmods the directory immediately after (or each part of the
|
84
|
+
* path if requested).
|
85
|
+
*
|
86
|
+
* @param path The path to create.
|
87
|
+
* @param base Root for relative path. These directories will never be made.
|
88
|
+
* @param mode The mode to use for created directories.
|
89
|
+
* @param flags Combination of the mkdir flags above.
|
90
|
+
* @return 0 on success, else error code
|
91
|
+
*/
|
92
|
+
extern int git_futils_mkdir(const char *path, const char *base, mode_t mode, uint32_t flags);
|
93
|
+
|
58
94
|
/**
|
59
95
|
* Create all the folders required to contain
|
60
96
|
* the full path of a file
|
@@ -71,15 +107,17 @@ typedef enum {
|
|
71
107
|
* Remove path and any files and directories beneath it.
|
72
108
|
*
|
73
109
|
* @param path Path to to top level directory to process.
|
74
|
-
*
|
110
|
+
* @param base Root for relative path.
|
75
111
|
* @param removal_type GIT_DIRREMOVAL_EMPTY_HIERARCHY to remove a hierarchy
|
76
|
-
*
|
77
|
-
* to remove a hierarchy of
|
78
|
-
*
|
112
|
+
* of empty directories (will fail if any file is found),
|
113
|
+
* GIT_DIRREMOVAL_FILES_AND_DIRS to remove a hierarchy of
|
114
|
+
* files and folders,
|
115
|
+
* GIT_DIRREMOVAL_ONLY_EMPTY_DIRS to only remove empty
|
116
|
+
* directories (no failure on file encounter).
|
79
117
|
*
|
80
118
|
* @return 0 on success; -1 on error.
|
81
119
|
*/
|
82
|
-
extern int git_futils_rmdir_r(const char *path, git_directory_removal_type removal_type);
|
120
|
+
extern int git_futils_rmdir_r(const char *path, const char *base, git_directory_removal_type removal_type);
|
83
121
|
|
84
122
|
/**
|
85
123
|
* Create and open a temporary file with a `_git2_` suffix.
|
@@ -94,6 +132,45 @@ extern int git_futils_mktmp(git_buf *path_out, const char *filename);
|
|
94
132
|
*/
|
95
133
|
extern int git_futils_mv_withpath(const char *from, const char *to, const mode_t dirmode);
|
96
134
|
|
135
|
+
/**
|
136
|
+
* Copy a file
|
137
|
+
*
|
138
|
+
* The filemode will be used for the newly created file.
|
139
|
+
*/
|
140
|
+
extern int git_futils_cp(
|
141
|
+
const char *from,
|
142
|
+
const char *to,
|
143
|
+
mode_t filemode);
|
144
|
+
|
145
|
+
/**
|
146
|
+
* Flags that can be passed to `git_futils_cp_r`.
|
147
|
+
*/
|
148
|
+
typedef enum {
|
149
|
+
GIT_CPDIR_CREATE_EMPTY_DIRS = 1,
|
150
|
+
GIT_CPDIR_COPY_SYMLINKS = 2,
|
151
|
+
GIT_CPDIR_COPY_DOTFILES = 4,
|
152
|
+
GIT_CPDIR_OVERWRITE = 8,
|
153
|
+
GIT_CPDIR_CHMOD = 16
|
154
|
+
} git_futils_cpdir_flags;
|
155
|
+
|
156
|
+
/**
|
157
|
+
* Copy a directory tree.
|
158
|
+
*
|
159
|
+
* This copies directories and files from one root to another. You can
|
160
|
+
* pass a combinationof GIT_CPDIR flags as defined above.
|
161
|
+
*
|
162
|
+
* If you pass the CHMOD flag, then the dirmode will be applied to all
|
163
|
+
* directories that are created during the copy, overiding the natural
|
164
|
+
* permissions. If you do not pass the CHMOD flag, then the dirmode
|
165
|
+
* will actually be copied from the source files and the `dirmode` arg
|
166
|
+
* will be ignored.
|
167
|
+
*/
|
168
|
+
extern int git_futils_cp_r(
|
169
|
+
const char *from,
|
170
|
+
const char *to,
|
171
|
+
uint32_t flags,
|
172
|
+
mode_t dirmode);
|
173
|
+
|
97
174
|
/**
|
98
175
|
* Open a file readonly and set error if needed.
|
99
176
|
*/
|
data/vendor/libgit2/src/filter.c
CHANGED
@@ -164,38 +164,3 @@ int git_filters_apply(git_buf *dest, git_buf *source, git_vector *filters)
|
|
164
164
|
|
165
165
|
return 0;
|
166
166
|
}
|
167
|
-
|
168
|
-
static int unfiltered_blob_contents(git_buf *out, git_repository *repo, const git_oid *blob_id)
|
169
|
-
{
|
170
|
-
int retcode = GIT_ERROR;
|
171
|
-
git_blob *blob;
|
172
|
-
|
173
|
-
if (!(retcode = git_blob_lookup(&blob, repo, blob_id)))
|
174
|
-
{
|
175
|
-
retcode = git_blob__getbuf(out, blob);
|
176
|
-
git_blob_free(blob);
|
177
|
-
}
|
178
|
-
|
179
|
-
return retcode;
|
180
|
-
}
|
181
|
-
|
182
|
-
int git_filter_blob_contents(git_buf *out, git_repository *repo, const git_oid *oid, const char *path)
|
183
|
-
{
|
184
|
-
int retcode = GIT_ERROR;
|
185
|
-
|
186
|
-
git_buf unfiltered = GIT_BUF_INIT;
|
187
|
-
if (!unfiltered_blob_contents(&unfiltered, repo, oid)) {
|
188
|
-
git_vector filters = GIT_VECTOR_INIT;
|
189
|
-
if (git_filters_load(&filters,
|
190
|
-
repo, path, GIT_FILTER_TO_WORKTREE) >= 0) {
|
191
|
-
git_buf_clear(out);
|
192
|
-
retcode = git_filters_apply(out, &unfiltered, &filters);
|
193
|
-
}
|
194
|
-
|
195
|
-
git_filters_free(&filters);
|
196
|
-
}
|
197
|
-
|
198
|
-
git_buf_free(&unfiltered);
|
199
|
-
return retcode;
|
200
|
-
}
|
201
|
-
|
data/vendor/libgit2/src/filter.h
CHANGED
@@ -119,16 +119,4 @@ extern void git_text_gather_stats(git_text_stats *stats, const git_buf *text);
|
|
119
119
|
*/
|
120
120
|
extern int git_text_is_binary(git_text_stats *stats);
|
121
121
|
|
122
|
-
|
123
|
-
/**
|
124
|
-
* Get the content of a blob after all filters have been run.
|
125
|
-
*
|
126
|
-
* @param out buffer to receive the contents
|
127
|
-
* @param repo repository containing the blob
|
128
|
-
* @param oid object id for the blob
|
129
|
-
* @param path path to the blob's output file, relative to the workdir root
|
130
|
-
* @return 0 on success, an error code otherwise
|
131
|
-
*/
|
132
|
-
extern int git_filter_blob_contents(git_buf *out, git_repository *repo, const git_oid *oid, const char *path);
|
133
|
-
|
134
122
|
#endif
|
@@ -24,13 +24,16 @@
|
|
24
24
|
|
25
25
|
static int rangematch(const char *, char, int, char **);
|
26
26
|
|
27
|
-
int
|
28
|
-
|
27
|
+
static int
|
28
|
+
p_fnmatchx(const char *pattern, const char *string, int flags, size_t recurs)
|
29
29
|
{
|
30
30
|
const char *stringstart;
|
31
31
|
char *newp;
|
32
32
|
char c, test;
|
33
33
|
|
34
|
+
if (recurs-- == 0)
|
35
|
+
return FNM_NORES;
|
36
|
+
|
34
37
|
for (stringstart = string;;)
|
35
38
|
switch (c = *pattern++) {
|
36
39
|
case EOS:
|
@@ -75,8 +78,11 @@ p_fnmatch(const char *pattern, const char *string, int flags)
|
|
75
78
|
|
76
79
|
/* General case, use recursion. */
|
77
80
|
while ((test = *string) != EOS) {
|
78
|
-
|
79
|
-
|
81
|
+
int e;
|
82
|
+
|
83
|
+
e = p_fnmatchx(pattern, string, flags & ~FNM_PERIOD, recurs);
|
84
|
+
if (e != FNM_NOMATCH)
|
85
|
+
return e;
|
80
86
|
if (test == '/' && (flags & FNM_PATHNAME))
|
81
87
|
break;
|
82
88
|
++string;
|
@@ -178,3 +184,9 @@ rangematch(const char *pattern, char test, int flags, char **newp)
|
|
178
184
|
return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH);
|
179
185
|
}
|
180
186
|
|
187
|
+
int
|
188
|
+
p_fnmatch(const char *pattern, const char *string, int flags)
|
189
|
+
{
|
190
|
+
return p_fnmatchx(pattern, string, flags, 64);
|
191
|
+
}
|
192
|
+
|
@@ -11,12 +11,13 @@
|
|
11
11
|
|
12
12
|
#define FNM_NOMATCH 1 /* Match failed. */
|
13
13
|
#define FNM_NOSYS 2 /* Function not supported (unused). */
|
14
|
+
#define FNM_NORES 3 /* Out of resources */
|
14
15
|
|
15
|
-
#define FNM_NOESCAPE
|
16
|
-
#define FNM_PATHNAME
|
16
|
+
#define FNM_NOESCAPE 0x01 /* Disable backslash escaping. */
|
17
|
+
#define FNM_PATHNAME 0x02 /* Slash must be matched by slash. */
|
17
18
|
#define FNM_PERIOD 0x04 /* Period must be matched by period. */
|
18
19
|
#define FNM_LEADING_DIR 0x08 /* Ignore /<tail> after Imatch. */
|
19
|
-
#define FNM_CASEFOLD
|
20
|
+
#define FNM_CASEFOLD 0x10 /* Case insensitive search. */
|
20
21
|
|
21
22
|
#define FNM_IGNORECASE FNM_CASEFOLD
|
22
23
|
#define FNM_FILE_NAME FNM_PATHNAME
|
data/vendor/libgit2/src/global.c
CHANGED
@@ -64,6 +64,8 @@ git_global_st *git__global_state(void)
|
|
64
64
|
{
|
65
65
|
void *ptr;
|
66
66
|
|
67
|
+
assert(_tls_init);
|
68
|
+
|
67
69
|
if ((ptr = TlsGetValue(_tls_index)) != NULL)
|
68
70
|
return ptr;
|
69
71
|
|
@@ -105,6 +107,8 @@ git_global_st *git__global_state(void)
|
|
105
107
|
{
|
106
108
|
void *ptr;
|
107
109
|
|
110
|
+
assert(_tls_init);
|
111
|
+
|
108
112
|
if ((ptr = pthread_getspecific(_tls_key)) != NULL)
|
109
113
|
return ptr;
|
110
114
|
|
data/vendor/libgit2/src/ignore.c
CHANGED
@@ -1,20 +1,37 @@
|
|
1
1
|
#include "git2/ignore.h"
|
2
2
|
#include "ignore.h"
|
3
3
|
#include "path.h"
|
4
|
+
#include "config.h"
|
4
5
|
|
5
6
|
#define GIT_IGNORE_INTERNAL "[internal]exclude"
|
6
7
|
#define GIT_IGNORE_FILE_INREPO "info/exclude"
|
7
8
|
#define GIT_IGNORE_FILE ".gitignore"
|
8
9
|
|
9
10
|
static int parse_ignore_file(
|
10
|
-
git_repository *repo, const char *buffer, git_attr_file *ignores)
|
11
|
+
git_repository *repo, void *parsedata, const char *buffer, git_attr_file *ignores)
|
11
12
|
{
|
12
13
|
int error = 0;
|
13
14
|
git_attr_fnmatch *match = NULL;
|
14
15
|
const char *scan = NULL;
|
15
16
|
char *context = NULL;
|
16
|
-
|
17
|
-
|
17
|
+
bool ignore_case = false;
|
18
|
+
git_config *cfg = NULL;
|
19
|
+
int val;
|
20
|
+
|
21
|
+
/* Prefer to have the caller pass in a git_ignores as the parsedata object.
|
22
|
+
* If they did not, then we can (much more slowly) find the value of
|
23
|
+
* ignore_case by using the repository object. */
|
24
|
+
if (parsedata != NULL) {
|
25
|
+
ignore_case = ((git_ignores *)parsedata)->ignore_case;
|
26
|
+
} else {
|
27
|
+
if ((error = git_repository_config(&cfg, repo)) < 0)
|
28
|
+
return error;
|
29
|
+
|
30
|
+
if (git_config_get_bool(&val, cfg, "core.ignorecase") == 0)
|
31
|
+
ignore_case = (val != 0);
|
32
|
+
|
33
|
+
git_config_free(cfg);
|
34
|
+
}
|
18
35
|
|
19
36
|
if (ignores->key && git__suffixcmp(ignores->key, "/" GIT_IGNORE_FILE) == 0) {
|
20
37
|
context = ignores->key + 2;
|
@@ -34,7 +51,11 @@ static int parse_ignore_file(
|
|
34
51
|
if (!(error = git_attr_fnmatch__parse(
|
35
52
|
match, ignores->pool, context, &scan)))
|
36
53
|
{
|
37
|
-
match->flags
|
54
|
+
match->flags |= GIT_ATTR_FNMATCH_IGNORE;
|
55
|
+
|
56
|
+
if (ignore_case)
|
57
|
+
match->flags |= GIT_ATTR_FNMATCH_ICASE;
|
58
|
+
|
38
59
|
scan = git__next_line(scan);
|
39
60
|
error = git_vector_insert(&ignores->rules, match);
|
40
61
|
}
|
@@ -58,13 +79,13 @@ static int parse_ignore_file(
|
|
58
79
|
return error;
|
59
80
|
}
|
60
81
|
|
61
|
-
#define push_ignore_file(R,S,B,F) \
|
62
|
-
git_attr_cache__push_file((R),(B),(F),GIT_ATTR_FILE_FROM_FILE,parse_ignore_file,(S))
|
82
|
+
#define push_ignore_file(R,IGN,S,B,F) \
|
83
|
+
git_attr_cache__push_file((R),(B),(F),GIT_ATTR_FILE_FROM_FILE,parse_ignore_file,(IGN),(S))
|
63
84
|
|
64
85
|
static int push_one_ignore(void *ref, git_buf *path)
|
65
86
|
{
|
66
87
|
git_ignores *ign = (git_ignores *)ref;
|
67
|
-
return push_ignore_file(ign->repo, &ign->ign_path, path->ptr, GIT_IGNORE_FILE);
|
88
|
+
return push_ignore_file(ign->repo, ign, &ign->ign_path, path->ptr, GIT_IGNORE_FILE);
|
68
89
|
}
|
69
90
|
|
70
91
|
int git_ignore__for_path(
|
@@ -74,6 +95,8 @@ int git_ignore__for_path(
|
|
74
95
|
{
|
75
96
|
int error = 0;
|
76
97
|
const char *workdir = git_repository_workdir(repo);
|
98
|
+
git_config *cfg = NULL;
|
99
|
+
int val;
|
77
100
|
|
78
101
|
assert(ignores);
|
79
102
|
|
@@ -81,6 +104,17 @@ int git_ignore__for_path(
|
|
81
104
|
git_buf_init(&ignores->dir, 0);
|
82
105
|
ignores->ign_internal = NULL;
|
83
106
|
|
107
|
+
/* Set the ignore_case flag appropriately */
|
108
|
+
if ((error = git_repository_config(&cfg, repo)) < 0)
|
109
|
+
goto cleanup;
|
110
|
+
|
111
|
+
if (git_config_get_bool(&val, cfg, "core.ignorecase") == 0)
|
112
|
+
ignores->ignore_case = (val != 0);
|
113
|
+
else
|
114
|
+
ignores->ignore_case = 0;
|
115
|
+
|
116
|
+
git_config_free(cfg);
|
117
|
+
|
84
118
|
if ((error = git_vector_init(&ignores->ign_path, 8, NULL)) < 0 ||
|
85
119
|
(error = git_vector_init(&ignores->ign_global, 2, NULL)) < 0 ||
|
86
120
|
(error = git_attr_cache__init(repo)) < 0)
|
@@ -109,14 +143,14 @@ int git_ignore__for_path(
|
|
109
143
|
}
|
110
144
|
|
111
145
|
/* load .git/info/exclude */
|
112
|
-
error = push_ignore_file(repo, &ignores->ign_global,
|
146
|
+
error = push_ignore_file(repo, ignores, &ignores->ign_global,
|
113
147
|
git_repository_path(repo), GIT_IGNORE_FILE_INREPO);
|
114
148
|
if (error < 0)
|
115
149
|
goto cleanup;
|
116
150
|
|
117
151
|
/* load core.excludesfile */
|
118
152
|
if (git_repository_attr_cache(repo)->cfg_excl_file != NULL)
|
119
|
-
error = push_ignore_file(repo, &ignores->ign_global, NULL,
|
153
|
+
error = push_ignore_file(repo, ignores, &ignores->ign_global, NULL,
|
120
154
|
git_repository_attr_cache(repo)->cfg_excl_file);
|
121
155
|
|
122
156
|
cleanup:
|
@@ -132,7 +166,7 @@ int git_ignore__push_dir(git_ignores *ign, const char *dir)
|
|
132
166
|
return -1;
|
133
167
|
else
|
134
168
|
return push_ignore_file(
|
135
|
-
ign->repo, &ign->ign_path, ign->dir.ptr, GIT_IGNORE_FILE);
|
169
|
+
ign->repo, ign, &ign->ign_path, ign->dir.ptr, GIT_IGNORE_FILE);
|
136
170
|
}
|
137
171
|
|
138
172
|
int git_ignore__pop_dir(git_ignores *ign)
|
@@ -205,6 +239,16 @@ cleanup:
|
|
205
239
|
return 0;
|
206
240
|
}
|
207
241
|
|
242
|
+
static int get_internal_ignores(git_attr_file **ign, git_repository *repo)
|
243
|
+
{
|
244
|
+
int error;
|
245
|
+
|
246
|
+
if (!(error = git_attr_cache__init(repo)))
|
247
|
+
error = git_attr_cache__internal_file(repo, GIT_IGNORE_INTERNAL, ign);
|
248
|
+
|
249
|
+
return error;
|
250
|
+
}
|
251
|
+
|
208
252
|
int git_ignore_add_rule(
|
209
253
|
git_repository *repo,
|
210
254
|
const char *rules)
|
@@ -212,11 +256,8 @@ int git_ignore_add_rule(
|
|
212
256
|
int error;
|
213
257
|
git_attr_file *ign_internal;
|
214
258
|
|
215
|
-
error =
|
216
|
-
repo,
|
217
|
-
|
218
|
-
if (!error && ign_internal != NULL)
|
219
|
-
error = parse_ignore_file(repo, rules, ign_internal);
|
259
|
+
if (!(error = get_internal_ignores(&ign_internal, repo)))
|
260
|
+
error = parse_ignore_file(repo, NULL, rules, ign_internal);
|
220
261
|
|
221
262
|
return error;
|
222
263
|
}
|
@@ -227,10 +268,7 @@ int git_ignore_clear_internal_rules(
|
|
227
268
|
int error;
|
228
269
|
git_attr_file *ign_internal;
|
229
270
|
|
230
|
-
error =
|
231
|
-
repo, GIT_IGNORE_INTERNAL, &ign_internal);
|
232
|
-
|
233
|
-
if (!error && ign_internal != NULL)
|
271
|
+
if (!(error = get_internal_ignores(&ign_internal, repo)))
|
234
272
|
git_attr_file__clear_rules(ign_internal);
|
235
273
|
|
236
274
|
return error;
|
@@ -239,15 +277,76 @@ int git_ignore_clear_internal_rules(
|
|
239
277
|
int git_ignore_path_is_ignored(
|
240
278
|
int *ignored,
|
241
279
|
git_repository *repo,
|
242
|
-
const char *
|
280
|
+
const char *pathname)
|
243
281
|
{
|
244
282
|
int error;
|
283
|
+
const char *workdir;
|
284
|
+
git_attr_path path;
|
285
|
+
char *tail, *end;
|
286
|
+
bool full_is_dir;
|
245
287
|
git_ignores ignores;
|
288
|
+
unsigned int i;
|
289
|
+
git_attr_file *file;
|
246
290
|
|
247
|
-
|
248
|
-
|
291
|
+
assert(ignored && pathname);
|
292
|
+
|
293
|
+
workdir = repo ? git_repository_workdir(repo) : NULL;
|
294
|
+
|
295
|
+
if ((error = git_attr_path__init(&path, pathname, workdir)) < 0)
|
296
|
+
return error;
|
297
|
+
|
298
|
+
tail = path.path;
|
299
|
+
end = &path.full.ptr[path.full.size];
|
300
|
+
full_is_dir = path.is_dir;
|
301
|
+
|
302
|
+
while (1) {
|
303
|
+
/* advance to next component of path */
|
304
|
+
path.basename = tail;
|
305
|
+
|
306
|
+
while (tail < end && *tail != '/') tail++;
|
307
|
+
*tail = '\0';
|
308
|
+
|
309
|
+
path.full.size = (tail - path.full.ptr);
|
310
|
+
path.is_dir = (tail == end) ? full_is_dir : true;
|
311
|
+
|
312
|
+
/* update ignores for new path fragment */
|
313
|
+
if (path.basename == path.path)
|
314
|
+
error = git_ignore__for_path(repo, path.path, &ignores);
|
315
|
+
else
|
316
|
+
error = git_ignore__push_dir(&ignores, path.basename);
|
317
|
+
if (error < 0)
|
318
|
+
break;
|
319
|
+
|
320
|
+
/* first process builtins - success means path was found */
|
321
|
+
if (ignore_lookup_in_rules(
|
322
|
+
&ignores.ign_internal->rules, &path, ignored))
|
323
|
+
goto cleanup;
|
249
324
|
|
250
|
-
|
325
|
+
/* next process files in the path */
|
326
|
+
git_vector_foreach(&ignores.ign_path, i, file) {
|
327
|
+
if (ignore_lookup_in_rules(&file->rules, &path, ignored))
|
328
|
+
goto cleanup;
|
329
|
+
}
|
330
|
+
|
331
|
+
/* last process global ignores */
|
332
|
+
git_vector_foreach(&ignores.ign_global, i, file) {
|
333
|
+
if (ignore_lookup_in_rules(&file->rules, &path, ignored))
|
334
|
+
goto cleanup;
|
335
|
+
}
|
336
|
+
|
337
|
+
/* if we found no rules before reaching the end, we're done */
|
338
|
+
if (tail == end)
|
339
|
+
break;
|
340
|
+
|
341
|
+
/* reinstate divider in path */
|
342
|
+
*tail = '/';
|
343
|
+
while (*tail == '/') tail++;
|
344
|
+
}
|
345
|
+
|
346
|
+
*ignored = 0;
|
347
|
+
|
348
|
+
cleanup:
|
349
|
+
git_attr_path__free(&path);
|
251
350
|
git_ignore__free(&ignores);
|
252
351
|
return error;
|
253
352
|
}
|