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
@@ -0,0 +1,102 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (C) 2012 the libgit2 contributors
|
3
|
+
*
|
4
|
+
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
5
|
+
* a Linking Exception. For full terms see the included COPYING file.
|
6
|
+
*/
|
7
|
+
#ifndef INCLUDE_submodule_h__
|
8
|
+
#define INCLUDE_submodule_h__
|
9
|
+
|
10
|
+
/* Notes:
|
11
|
+
*
|
12
|
+
* Submodule information can be in four places: the index, the config files
|
13
|
+
* (both .git/config and .gitmodules), the HEAD tree, and the working
|
14
|
+
* directory.
|
15
|
+
*
|
16
|
+
* In the index:
|
17
|
+
* - submodule is found by path
|
18
|
+
* - may be missing, present, or of the wrong type
|
19
|
+
* - will have an oid if present
|
20
|
+
*
|
21
|
+
* In the HEAD tree:
|
22
|
+
* - submodule is found by path
|
23
|
+
* - may be missing, present, or of the wrong type
|
24
|
+
* - will have an oid if present
|
25
|
+
*
|
26
|
+
* In the config files:
|
27
|
+
* - submodule is found by submodule "name" which is usually the path
|
28
|
+
* - may be missing or present
|
29
|
+
* - will have a name, path, url, and other properties
|
30
|
+
*
|
31
|
+
* In the working directory:
|
32
|
+
* - submodule is found by path
|
33
|
+
* - may be missing, an empty directory, a checked out directory,
|
34
|
+
* or of the wrong type
|
35
|
+
* - if checked out, will have a HEAD oid
|
36
|
+
* - if checked out, will have git history that can be used to compare oids
|
37
|
+
* - if checked out, may have modified files and/or untracked files
|
38
|
+
*/
|
39
|
+
|
40
|
+
/**
|
41
|
+
* Description of submodule
|
42
|
+
*
|
43
|
+
* This record describes a submodule found in a repository. There should be
|
44
|
+
* an entry for every submodule found in the HEAD and index, and for every
|
45
|
+
* submodule described in .gitmodules. The fields are as follows:
|
46
|
+
*
|
47
|
+
* - `owner` is the git_repository containing this submodule
|
48
|
+
* - `name` is the name of the submodule from .gitmodules.
|
49
|
+
* - `path` is the path to the submodule from the repo root. It is almost
|
50
|
+
* always the same as `name`.
|
51
|
+
* - `url` is the url for the submodule.
|
52
|
+
* - `tree_oid` is the SHA1 for the submodule path in the repo HEAD.
|
53
|
+
* - `index_oid` is the SHA1 for the submodule recorded in the index.
|
54
|
+
* - `workdir_oid` is the SHA1 for the HEAD of the checked out submodule.
|
55
|
+
* - `update` is a git_submodule_update_t value - see gitmodules(5) update.
|
56
|
+
* - `ignore` is a git_submodule_ignore_t value - see gitmodules(5) ignore.
|
57
|
+
* - `fetch_recurse` is 0 or 1 - see gitmodules(5) fetchRecurseSubmodules.
|
58
|
+
* - `refcount` tracks how many hashmap entries there are for this submodule.
|
59
|
+
* It only comes into play if the name and path of the submodule differ.
|
60
|
+
* - `flags` is for internal use, tracking where this submodule has been
|
61
|
+
* found (head, index, config, workdir) and other misc info about it.
|
62
|
+
*
|
63
|
+
* If the submodule has been added to .gitmodules but not yet git added,
|
64
|
+
* then the `index_oid` will be valid and zero. If the submodule has been
|
65
|
+
* deleted, but the delete has not been committed yet, then the `index_oid`
|
66
|
+
* will be set, but the `url` will be NULL.
|
67
|
+
*/
|
68
|
+
struct git_submodule {
|
69
|
+
git_repository *owner;
|
70
|
+
char *name;
|
71
|
+
char *path; /* important: may point to same string data as "name" */
|
72
|
+
char *url;
|
73
|
+
uint32_t flags;
|
74
|
+
git_oid head_oid;
|
75
|
+
git_oid index_oid;
|
76
|
+
git_oid wd_oid;
|
77
|
+
/* information from config */
|
78
|
+
git_submodule_update_t update;
|
79
|
+
git_submodule_update_t update_default;
|
80
|
+
git_submodule_ignore_t ignore;
|
81
|
+
git_submodule_ignore_t ignore_default;
|
82
|
+
int fetch_recurse;
|
83
|
+
/* internal information */
|
84
|
+
int refcount;
|
85
|
+
};
|
86
|
+
|
87
|
+
/* Additional flags on top of public GIT_SUBMODULE_STATUS values */
|
88
|
+
enum {
|
89
|
+
GIT_SUBMODULE_STATUS__WD_SCANNED = (1u << 20),
|
90
|
+
GIT_SUBMODULE_STATUS__HEAD_OID_VALID = (1u << 21),
|
91
|
+
GIT_SUBMODULE_STATUS__INDEX_OID_VALID = (1u << 22),
|
92
|
+
GIT_SUBMODULE_STATUS__WD_OID_VALID = (1u << 23),
|
93
|
+
GIT_SUBMODULE_STATUS__HEAD_NOT_SUBMODULE = (1u << 24),
|
94
|
+
GIT_SUBMODULE_STATUS__INDEX_NOT_SUBMODULE = (1u << 25),
|
95
|
+
GIT_SUBMODULE_STATUS__WD_NOT_SUBMODULE = (1u << 26),
|
96
|
+
GIT_SUBMODULE_STATUS__INDEX_MULTIPLE_ENTRIES = (1u << 27),
|
97
|
+
};
|
98
|
+
|
99
|
+
#define GIT_SUBMODULE_STATUS__CLEAR_INTERNAL(S) \
|
100
|
+
((S) & ~(0xFFFFFFFFu << 20))
|
101
|
+
|
102
|
+
#endif
|
data/vendor/libgit2/src/tag.c
CHANGED
@@ -393,22 +393,53 @@ int git_tag__parse(git_tag *tag, git_odb_object *obj)
|
|
393
393
|
}
|
394
394
|
|
395
395
|
typedef struct {
|
396
|
-
|
397
|
-
|
396
|
+
git_repository *repo;
|
397
|
+
git_tag_foreach_cb cb;
|
398
|
+
void *cb_data;
|
399
|
+
} tag_cb_data;
|
400
|
+
|
401
|
+
static int tags_cb(const char *ref, void *data)
|
402
|
+
{
|
403
|
+
git_oid oid;
|
404
|
+
tag_cb_data *d = (tag_cb_data *)data;
|
405
|
+
|
406
|
+
if (git__prefixcmp(ref, GIT_REFS_TAGS_DIR) != 0)
|
407
|
+
return 0; /* no tag */
|
408
|
+
|
409
|
+
if (git_reference_name_to_oid(&oid, d->repo, ref) < 0)
|
410
|
+
return -1;
|
411
|
+
|
412
|
+
return d->cb(ref, &oid, d->cb_data);
|
413
|
+
}
|
414
|
+
|
415
|
+
int git_tag_foreach(git_repository *repo, git_tag_foreach_cb cb, void *cb_data)
|
416
|
+
{
|
417
|
+
tag_cb_data data;
|
418
|
+
|
419
|
+
assert(repo && cb);
|
420
|
+
|
421
|
+
data.cb = cb;
|
422
|
+
data.cb_data = cb_data;
|
423
|
+
data.repo = repo;
|
424
|
+
|
425
|
+
return git_reference_foreach(repo, GIT_REF_OID | GIT_REF_PACKED,
|
426
|
+
&tags_cb, &data);
|
427
|
+
}
|
428
|
+
|
429
|
+
typedef struct {
|
430
|
+
git_vector *taglist;
|
431
|
+
const char *pattern;
|
398
432
|
} tag_filter_data;
|
399
433
|
|
400
434
|
#define GIT_REFS_TAGS_DIR_LEN strlen(GIT_REFS_TAGS_DIR)
|
401
435
|
|
402
|
-
static int tag_list_cb(const char *tag_name, void *
|
436
|
+
static int tag_list_cb(const char *tag_name, git_oid *oid, void *data)
|
403
437
|
{
|
404
|
-
tag_filter_data *filter;
|
438
|
+
tag_filter_data *filter = (tag_filter_data *)data;
|
439
|
+
GIT_UNUSED(oid);
|
405
440
|
|
406
|
-
if (git__prefixcmp(tag_name, GIT_REFS_TAGS_DIR) != 0)
|
407
|
-
return 0;
|
408
|
-
|
409
|
-
filter = (tag_filter_data *)payload;
|
410
441
|
if (!*filter->pattern || p_fnmatch(filter->pattern, tag_name + GIT_REFS_TAGS_DIR_LEN, 0) == 0)
|
411
|
-
return git_vector_insert(filter->taglist, git__strdup(tag_name));
|
442
|
+
return git_vector_insert(filter->taglist, git__strdup(tag_name + GIT_REFS_TAGS_DIR_LEN));
|
412
443
|
|
413
444
|
return 0;
|
414
445
|
}
|
@@ -427,7 +458,7 @@ int git_tag_list_match(git_strarray *tag_names, const char *pattern, git_reposit
|
|
427
458
|
filter.taglist = &taglist;
|
428
459
|
filter.pattern = pattern;
|
429
460
|
|
430
|
-
error =
|
461
|
+
error = git_tag_foreach(repo, &tag_list_cb, (void *)&filter);
|
431
462
|
if (error < 0) {
|
432
463
|
git_vector_free(&taglist);
|
433
464
|
return -1;
|
@@ -445,20 +476,5 @@ int git_tag_list(git_strarray *tag_names, git_repository *repo)
|
|
445
476
|
|
446
477
|
int git_tag_peel(git_object **tag_target, git_tag *tag)
|
447
478
|
{
|
448
|
-
|
449
|
-
git_object *target;
|
450
|
-
|
451
|
-
assert(tag_target && tag);
|
452
|
-
|
453
|
-
if (git_tag_target(&target, tag) < 0)
|
454
|
-
return -1;
|
455
|
-
|
456
|
-
if (git_object_type(target) == GIT_OBJ_TAG) {
|
457
|
-
error = git_tag_peel(tag_target, (git_tag *)target);
|
458
|
-
git_object_free(target);
|
459
|
-
return error;
|
460
|
-
}
|
461
|
-
|
462
|
-
*tag_target = target;
|
463
|
-
return 0;
|
479
|
+
return git_object_peel(tag_target, (git_object *)tag, GIT_OBJ_ANY);
|
464
480
|
}
|
@@ -38,13 +38,13 @@ GIT_INLINE(void) git_atomic_set(git_atomic *a, int val)
|
|
38
38
|
#define git_mutex_unlock(a) pthread_mutex_unlock(a)
|
39
39
|
#define git_mutex_free(a) pthread_mutex_destroy(a)
|
40
40
|
|
41
|
-
/* Pthreads condition vars
|
42
|
-
#define git_cond
|
43
|
-
#define git_cond_init(c
|
44
|
-
#define git_cond_free(c)
|
45
|
-
#define git_cond_wait(c, l)
|
46
|
-
#define git_cond_signal(c)
|
47
|
-
#define git_cond_broadcast(c)
|
41
|
+
/* Pthreads condition vars */
|
42
|
+
#define git_cond pthread_cond_t
|
43
|
+
#define git_cond_init(c) pthread_cond_init(c, NULL)
|
44
|
+
#define git_cond_free(c) pthread_cond_destroy(c)
|
45
|
+
#define git_cond_wait(c, l) pthread_cond_wait(c, l)
|
46
|
+
#define git_cond_signal(c) pthread_cond_signal(c)
|
47
|
+
#define git_cond_broadcast(c) pthread_cond_broadcast(c)
|
48
48
|
|
49
49
|
GIT_INLINE(int) git_atomic_inc(git_atomic *a)
|
50
50
|
{
|
@@ -21,11 +21,17 @@
|
|
21
21
|
|
22
22
|
#define GIT_CAP_OFS_DELTA "ofs-delta"
|
23
23
|
#define GIT_CAP_MULTI_ACK "multi_ack"
|
24
|
+
#define GIT_CAP_SIDE_BAND "side-band"
|
25
|
+
#define GIT_CAP_SIDE_BAND_64K "side-band-64k"
|
26
|
+
#define GIT_CAP_INCLUDE_TAG "include-tag"
|
24
27
|
|
25
28
|
typedef struct git_transport_caps {
|
26
29
|
int common:1,
|
27
30
|
ofs_delta:1,
|
28
|
-
multi_ack: 1
|
31
|
+
multi_ack: 1,
|
32
|
+
side_band:1,
|
33
|
+
side_band_64k:1,
|
34
|
+
include_tag:1;
|
29
35
|
} git_transport_caps;
|
30
36
|
|
31
37
|
#ifdef GIT_SSL
|
@@ -84,6 +90,9 @@ struct git_transport {
|
|
84
90
|
gitno_buffer buffer;
|
85
91
|
GIT_SOCKET socket;
|
86
92
|
git_transport_caps caps;
|
93
|
+
void *cb_data;
|
94
|
+
git_atomic cancel;
|
95
|
+
|
87
96
|
/**
|
88
97
|
* Connect and store the remote heads
|
89
98
|
*/
|
@@ -113,6 +122,11 @@ struct git_transport {
|
|
113
122
|
* Free the associated resources
|
114
123
|
*/
|
115
124
|
void (*free)(struct git_transport *transport);
|
125
|
+
/**
|
126
|
+
* Callbacks for the progress and error output
|
127
|
+
*/
|
128
|
+
void (*progress_cb)(const char *str, int len, void *data);
|
129
|
+
void (*error_cb)(const char *str, int len, void *data);
|
116
130
|
};
|
117
131
|
|
118
132
|
|
@@ -4,7 +4,6 @@
|
|
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.
|
6
6
|
*/
|
7
|
-
|
8
7
|
#include <stdlib.h>
|
9
8
|
#include "git2.h"
|
10
9
|
#include "http_parser.h"
|
@@ -20,6 +19,13 @@
|
|
20
19
|
#include "filebuf.h"
|
21
20
|
#include "repository.h"
|
22
21
|
#include "protocol.h"
|
22
|
+
#if GIT_WINHTTP
|
23
|
+
# include <winhttp.h>
|
24
|
+
# pragma comment(lib, "winhttp.lib")
|
25
|
+
#endif
|
26
|
+
|
27
|
+
#define WIDEN2(s) L ## s
|
28
|
+
#define WIDEN(s) WIDEN2(s)
|
23
29
|
|
24
30
|
enum last_cb {
|
25
31
|
NONE,
|
@@ -43,10 +49,15 @@ typedef struct {
|
|
43
49
|
char *host;
|
44
50
|
char *port;
|
45
51
|
char *service;
|
46
|
-
char buffer[
|
52
|
+
char buffer[65536];
|
47
53
|
#ifdef GIT_WIN32
|
48
54
|
WSADATA wsd;
|
49
55
|
#endif
|
56
|
+
#ifdef GIT_WINHTTP
|
57
|
+
HINTERNET session;
|
58
|
+
HINTERNET connection;
|
59
|
+
HINTERNET request;
|
60
|
+
#endif
|
50
61
|
} transport_http;
|
51
62
|
|
52
63
|
static int gen_request(git_buf *buf, const char *path, const char *host, const char *op,
|
@@ -77,17 +88,156 @@ static int gen_request(git_buf *buf, const char *path, const char *host, const c
|
|
77
88
|
return 0;
|
78
89
|
}
|
79
90
|
|
80
|
-
static int
|
91
|
+
static int send_request(transport_http *t, const char *service, void *data, ssize_t content_length, int ls)
|
92
|
+
{
|
93
|
+
#ifndef GIT_WINHTTP
|
94
|
+
git_buf request = GIT_BUF_INIT;
|
95
|
+
const char *verb;
|
96
|
+
int error = -1;
|
97
|
+
|
98
|
+
verb = ls ? "GET" : "POST";
|
99
|
+
/* Generate and send the HTTP request */
|
100
|
+
if (gen_request(&request, t->path, t->host, verb, service, content_length, ls) < 0) {
|
101
|
+
giterr_set(GITERR_NET, "Failed to generate request");
|
102
|
+
return -1;
|
103
|
+
}
|
104
|
+
|
105
|
+
|
106
|
+
if (gitno_send((git_transport *) t, request.ptr, request.size, 0) < 0)
|
107
|
+
goto cleanup;
|
108
|
+
|
109
|
+
if (content_length) {
|
110
|
+
if (gitno_send((git_transport *) t, data, content_length, 0) < 0)
|
111
|
+
goto cleanup;
|
112
|
+
}
|
113
|
+
|
114
|
+
error = 0;
|
115
|
+
|
116
|
+
cleanup:
|
117
|
+
git_buf_free(&request);
|
118
|
+
return error;
|
119
|
+
|
120
|
+
#else
|
121
|
+
wchar_t *verb;
|
122
|
+
wchar_t url[GIT_WIN_PATH], ct[GIT_WIN_PATH];
|
123
|
+
git_buf buf = GIT_BUF_INIT;
|
124
|
+
BOOL ret;
|
125
|
+
DWORD flags;
|
126
|
+
void *buffer;
|
127
|
+
wchar_t *types[] = {
|
128
|
+
L"*/*",
|
129
|
+
NULL,
|
130
|
+
};
|
131
|
+
|
132
|
+
verb = ls ? L"GET" : L"POST";
|
133
|
+
buffer = data ? data : WINHTTP_NO_REQUEST_DATA;
|
134
|
+
flags = t->parent.use_ssl ? WINHTTP_FLAG_SECURE : 0;
|
135
|
+
|
136
|
+
if (ls)
|
137
|
+
git_buf_printf(&buf, "%s/info/refs?service=git-%s", t->path, service);
|
138
|
+
else
|
139
|
+
git_buf_printf(&buf, "%s/git-%s", t->path, service);
|
140
|
+
|
141
|
+
if (git_buf_oom(&buf))
|
142
|
+
return -1;
|
143
|
+
|
144
|
+
git__utf8_to_16(url, GIT_WIN_PATH, git_buf_cstr(&buf));
|
145
|
+
|
146
|
+
t->request = WinHttpOpenRequest(t->connection, verb, url, NULL, WINHTTP_NO_REFERER, types, flags);
|
147
|
+
if (t->request == NULL) {
|
148
|
+
git_buf_free(&buf);
|
149
|
+
giterr_set(GITERR_OS, "Failed to open request");
|
150
|
+
return -1;
|
151
|
+
}
|
152
|
+
|
153
|
+
git_buf_clear(&buf);
|
154
|
+
if (git_buf_printf(&buf, "Content-Type: application/x-git-%s-request", service) < 0)
|
155
|
+
goto on_error;
|
156
|
+
|
157
|
+
git__utf8_to_16(ct, GIT_WIN_PATH, git_buf_cstr(&buf));
|
158
|
+
|
159
|
+
if (WinHttpAddRequestHeaders(t->request, ct, (ULONG) -1L, WINHTTP_ADDREQ_FLAG_ADD) == FALSE) {
|
160
|
+
giterr_set(GITERR_OS, "Failed to add a header to the request");
|
161
|
+
goto on_error;
|
162
|
+
}
|
163
|
+
|
164
|
+
if (!t->parent.check_cert) {
|
165
|
+
int flags = SECURITY_FLAG_IGNORE_CERT_CN_INVALID | SECURITY_FLAG_IGNORE_CERT_DATE_INVALID | SECURITY_FLAG_IGNORE_UNKNOWN_CA;
|
166
|
+
if (WinHttpSetOption(t->request, WINHTTP_OPTION_SECURITY_FLAGS, &flags, sizeof(flags)) == FALSE) {
|
167
|
+
giterr_set(GITERR_OS, "Failed to set options to ignore cert errors");
|
168
|
+
goto on_error;
|
169
|
+
}
|
170
|
+
}
|
171
|
+
|
172
|
+
if (WinHttpSendRequest(t->request, WINHTTP_NO_ADDITIONAL_HEADERS, 0,
|
173
|
+
data, (DWORD)content_length, (DWORD)content_length, 0) == FALSE) {
|
174
|
+
giterr_set(GITERR_OS, "Failed to send request");
|
175
|
+
goto on_error;
|
176
|
+
}
|
177
|
+
|
178
|
+
ret = WinHttpReceiveResponse(t->request, NULL);
|
179
|
+
if (ret == FALSE) {
|
180
|
+
giterr_set(GITERR_OS, "Failed to receive response");
|
181
|
+
goto on_error;
|
182
|
+
}
|
183
|
+
|
184
|
+
return 0;
|
185
|
+
|
186
|
+
on_error:
|
187
|
+
git_buf_free(&buf);
|
188
|
+
if (t->request)
|
189
|
+
WinHttpCloseHandle(t->request);
|
190
|
+
t->request = NULL;
|
191
|
+
return -1;
|
192
|
+
#endif
|
193
|
+
}
|
194
|
+
|
195
|
+
static int do_connect(transport_http *t)
|
81
196
|
{
|
197
|
+
#ifndef GIT_WINHTTP
|
82
198
|
if (t->parent.connected && http_should_keep_alive(&t->parser))
|
83
199
|
return 0;
|
84
200
|
|
85
|
-
if (gitno_connect((git_transport *) t, host, port) < 0)
|
201
|
+
if (gitno_connect((git_transport *) t, t->host, t->port) < 0)
|
86
202
|
return -1;
|
87
203
|
|
88
204
|
t->parent.connected = 1;
|
89
205
|
|
90
206
|
return 0;
|
207
|
+
#else
|
208
|
+
wchar_t *ua = L"git/1.0 (libgit2 " WIDEN(LIBGIT2_VERSION) L")";
|
209
|
+
wchar_t host[GIT_WIN_PATH];
|
210
|
+
int32_t port;
|
211
|
+
|
212
|
+
t->session = WinHttpOpen(ua, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
|
213
|
+
WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
|
214
|
+
|
215
|
+
if (t->session == NULL) {
|
216
|
+
giterr_set(GITERR_OS, "Failed to init WinHTTP");
|
217
|
+
goto on_error;
|
218
|
+
}
|
219
|
+
|
220
|
+
git__utf8_to_16(host, GIT_WIN_PATH, t->host);
|
221
|
+
|
222
|
+
if (git__strtol32(&port, t->port, NULL, 10) < 0)
|
223
|
+
goto on_error;
|
224
|
+
|
225
|
+
t->connection = WinHttpConnect(t->session, host, port, 0);
|
226
|
+
if (t->connection == NULL) {
|
227
|
+
giterr_set(GITERR_OS, "Failed to connect to host");
|
228
|
+
goto on_error;
|
229
|
+
}
|
230
|
+
|
231
|
+
t->parent.connected = 1;
|
232
|
+
return 0;
|
233
|
+
|
234
|
+
on_error:
|
235
|
+
if (t->session) {
|
236
|
+
WinHttpCloseHandle(t->session);
|
237
|
+
t->session = NULL;
|
238
|
+
}
|
239
|
+
return -1;
|
240
|
+
#endif
|
91
241
|
}
|
92
242
|
|
93
243
|
/*
|
@@ -216,13 +366,18 @@ static int http_recv_cb(gitno_buffer *buf)
|
|
216
366
|
git_transport *transport = (git_transport *) buf->cb_data;
|
217
367
|
transport_http *t = (transport_http *) transport;
|
218
368
|
size_t old_len;
|
219
|
-
gitno_buffer inner;
|
220
369
|
char buffer[2048];
|
370
|
+
#ifdef GIT_WINHTTP
|
371
|
+
DWORD recvd;
|
372
|
+
#else
|
373
|
+
gitno_buffer inner;
|
221
374
|
int error;
|
375
|
+
#endif
|
222
376
|
|
223
377
|
if (t->transfer_finished)
|
224
378
|
return 0;
|
225
379
|
|
380
|
+
#ifndef GIT_WINHTTP
|
226
381
|
gitno_buffer_setup(transport, &inner, buffer, sizeof(buffer));
|
227
382
|
|
228
383
|
if ((error = gitno_recv(&inner)) < 0)
|
@@ -232,8 +387,23 @@ static int http_recv_cb(gitno_buffer *buf)
|
|
232
387
|
http_parser_execute(&t->parser, &t->settings, inner.data, inner.offset);
|
233
388
|
if (t->error < 0)
|
234
389
|
return t->error;
|
390
|
+
#else
|
391
|
+
old_len = buf->offset;
|
392
|
+
if (WinHttpReadData(t->request, buffer, sizeof(buffer), &recvd) == FALSE) {
|
393
|
+
giterr_set(GITERR_OS, "Failed to read data from the network");
|
394
|
+
return t->error = -1;
|
395
|
+
}
|
396
|
+
|
397
|
+
if (buf->len - buf->offset < recvd) {
|
398
|
+
giterr_set(GITERR_NET, "Can't fit data in the buffer");
|
399
|
+
return t->error = -1;
|
400
|
+
}
|
401
|
+
|
402
|
+
memcpy(buf->data + buf->offset, buffer, recvd);
|
403
|
+
buf->offset += recvd;
|
404
|
+
#endif
|
235
405
|
|
236
|
-
return buf->offset - old_len;
|
406
|
+
return (int)(buf->offset - old_len);
|
237
407
|
}
|
238
408
|
|
239
409
|
/* Set up the gitno_buffer so calling gitno_recv() grabs data from the HTTP response */
|
@@ -241,6 +411,8 @@ static void setup_gitno_buffer(git_transport *transport)
|
|
241
411
|
{
|
242
412
|
transport_http *t = (transport_http *) transport;
|
243
413
|
|
414
|
+
/* WinHTTP takes care of this for us */
|
415
|
+
#ifndef GIT_WINHTTP
|
244
416
|
http_parser_init(&t->parser, HTTP_RESPONSE);
|
245
417
|
t->parser.data = t;
|
246
418
|
t->transfer_finished = 0;
|
@@ -250,6 +422,7 @@ static void setup_gitno_buffer(git_transport *transport)
|
|
250
422
|
t->settings.on_headers_complete = on_headers_complete;
|
251
423
|
t->settings.on_body = on_body_fill_buffer;
|
252
424
|
t->settings.on_message_complete = on_message_complete;
|
425
|
+
#endif
|
253
426
|
|
254
427
|
gitno_buffer_setup_callback(transport, &transport->buffer, t->buffer, sizeof(t->buffer), http_recv_cb, t);
|
255
428
|
}
|
@@ -289,17 +462,10 @@ static int http_connect(git_transport *transport, int direction)
|
|
289
462
|
t->service = git__strdup(service);
|
290
463
|
GITERR_CHECK_ALLOC(t->service);
|
291
464
|
|
292
|
-
if ((ret = do_connect(t
|
465
|
+
if ((ret = do_connect(t)) < 0)
|
293
466
|
goto cleanup;
|
294
467
|
|
295
|
-
|
296
|
-
if ((ret = gen_request(&request, t->path, t->host, "GET", service, 0, 1)) < 0) {
|
297
|
-
giterr_set(GITERR_NET, "Failed to generate request");
|
298
|
-
goto cleanup;
|
299
|
-
}
|
300
|
-
|
301
|
-
|
302
|
-
if (gitno_send(transport, request.ptr, request.size, 0) < 0)
|
468
|
+
if ((ret = send_request(t, "upload-pack", NULL, 0, 1)) < 0)
|
303
469
|
goto cleanup;
|
304
470
|
|
305
471
|
setup_gitno_buffer(transport);
|
@@ -311,10 +477,7 @@ static int http_connect(git_transport *transport, int direction)
|
|
311
477
|
giterr_set(GITERR_NET, "Invalid HTTP response");
|
312
478
|
return t->error = -1;
|
313
479
|
} else {
|
314
|
-
/* Remove the comment
|
315
|
-
git_vector_remove(&transport->refs, 0);
|
316
|
-
git__free(pkt);
|
317
|
-
pkt = git_vector_get(&transport->refs, 0);
|
480
|
+
/* Remove the comment pkt from the list */
|
318
481
|
git_vector_remove(&transport->refs, 0);
|
319
482
|
git__free(pkt);
|
320
483
|
}
|
@@ -332,36 +495,24 @@ cleanup:
|
|
332
495
|
static int http_negotiation_step(struct git_transport *transport, void *data, size_t len)
|
333
496
|
{
|
334
497
|
transport_http *t = (transport_http *) transport;
|
335
|
-
git_buf request = GIT_BUF_INIT;
|
336
498
|
int ret;
|
337
499
|
|
338
500
|
/* First, send the data as a HTTP POST request */
|
339
|
-
if ((ret = do_connect(t
|
501
|
+
if ((ret = do_connect(t)) < 0)
|
340
502
|
return -1;
|
341
503
|
|
342
|
-
if ((
|
343
|
-
|
344
|
-
|
345
|
-
if ((ret = gitno_send(transport, request.ptr, request.size, 0)) < 0)
|
346
|
-
goto on_error;
|
347
|
-
|
348
|
-
if ((ret = gitno_send(transport, data, len, 0)) < 0)
|
349
|
-
goto on_error;
|
350
|
-
|
351
|
-
git_buf_free(&request);
|
504
|
+
if (send_request(t, "upload-pack", data, len, 0) < 0)
|
505
|
+
return -1;
|
352
506
|
|
353
507
|
/* Then we need to set up the buffer to grab data from the HTTP response */
|
354
508
|
setup_gitno_buffer(transport);
|
355
509
|
|
356
510
|
return 0;
|
357
|
-
|
358
|
-
on_error:
|
359
|
-
git_buf_free(&request);
|
360
|
-
return -1;
|
361
511
|
}
|
362
512
|
|
363
513
|
static int http_close(git_transport *transport)
|
364
514
|
{
|
515
|
+
#ifndef GIT_WINHTTP
|
365
516
|
if (gitno_ssl_teardown(transport) < 0)
|
366
517
|
return -1;
|
367
518
|
|
@@ -369,6 +520,16 @@ static int http_close(git_transport *transport)
|
|
369
520
|
giterr_set(GITERR_OS, "Failed to close the socket: %s", strerror(errno));
|
370
521
|
return -1;
|
371
522
|
}
|
523
|
+
#else
|
524
|
+
transport_http *t = (transport_http *) transport;
|
525
|
+
|
526
|
+
if (t->request)
|
527
|
+
WinHttpCloseHandle(t->request);
|
528
|
+
if (t->connection)
|
529
|
+
WinHttpCloseHandle(t->connection);
|
530
|
+
if (t->session)
|
531
|
+
WinHttpCloseHandle(t->session);
|
532
|
+
#endif
|
372
533
|
|
373
534
|
transport->connected = 0;
|
374
535
|
|
@@ -445,7 +606,7 @@ int git_transport_http(git_transport **out)
|
|
445
606
|
|
446
607
|
int git_transport_https(git_transport **out)
|
447
608
|
{
|
448
|
-
#
|
609
|
+
#if defined(GIT_SSL) || defined(GIT_WINHTTP)
|
449
610
|
transport_http *t;
|
450
611
|
if (git_transport_http((git_transport **)&t) < 0)
|
451
612
|
return -1;
|