rugged 0.21.0 → 0.21.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rugged/version.rb +1 -1
  3. data/vendor/libgit2/include/git2/revert.h +1 -1
  4. data/vendor/libgit2/include/git2/transport.h +12 -10
  5. data/vendor/libgit2/include/git2/tree.h +2 -4
  6. data/vendor/libgit2/include/git2/version.h +2 -2
  7. data/vendor/libgit2/include/git2.h +1 -0
  8. data/vendor/libgit2/src/array.h +1 -1
  9. data/vendor/libgit2/src/buf_text.c +5 -9
  10. data/vendor/libgit2/src/buf_text.h +2 -3
  11. data/vendor/libgit2/src/cc-compat.h +8 -0
  12. data/vendor/libgit2/src/checkout.c +21 -3
  13. data/vendor/libgit2/src/config_file.c +11 -6
  14. data/vendor/libgit2/src/crlf.c +1 -2
  15. data/vendor/libgit2/src/diff_patch.c +1 -0
  16. data/vendor/libgit2/src/filebuf.c +2 -0
  17. data/vendor/libgit2/src/filter.c +11 -2
  18. data/vendor/libgit2/src/global.c +30 -2
  19. data/vendor/libgit2/src/index.c +29 -24
  20. data/vendor/libgit2/src/indexer.c +2 -9
  21. data/vendor/libgit2/src/merge.c +11 -3
  22. data/vendor/libgit2/src/mwindow.c +8 -117
  23. data/vendor/libgit2/src/mwindow.h +1 -9
  24. data/vendor/libgit2/src/netops.c +4 -1
  25. data/vendor/libgit2/src/odb_pack.c +3 -6
  26. data/vendor/libgit2/src/pack.c +5 -22
  27. data/vendor/libgit2/src/pack.h +0 -3
  28. data/vendor/libgit2/src/path.c +26 -16
  29. data/vendor/libgit2/src/pool.c +2 -2
  30. data/vendor/libgit2/src/refspec.c +42 -18
  31. data/vendor/libgit2/src/remote.c +13 -2
  32. data/vendor/libgit2/src/repository.c +3 -1
  33. data/vendor/libgit2/src/revwalk.c +0 -3
  34. data/vendor/libgit2/src/stash.c +5 -3
  35. data/vendor/libgit2/src/tag.c +3 -2
  36. data/vendor/libgit2/src/transports/http.c +20 -4
  37. data/vendor/libgit2/src/transports/ssh.c +23 -4
  38. data/vendor/libgit2/src/tree.c +60 -64
  39. data/vendor/libgit2/src/tree.h +3 -2
  40. data/vendor/libgit2/src/win32/posix_w32.c +14 -29
  41. metadata +68 -68
@@ -11,10 +11,6 @@
11
11
  #include "fileops.h"
12
12
  #include "map.h"
13
13
  #include "global.h"
14
- #include "strmap.h"
15
- #include "pack.h"
16
-
17
- GIT__USE_STRMAP;
18
14
 
19
15
  #define DEFAULT_WINDOW_SIZE \
20
16
  (sizeof(void*) >= 8 \
@@ -30,127 +26,20 @@ size_t git_mwindow__mapped_limit = DEFAULT_MAPPED_LIMIT;
30
26
  /* Whenever you want to read or modify this, grab git__mwindow_mutex */
31
27
  static git_mwindow_ctl mem_ctl;
32
28
 
33
- /* Global list of mwindow files, to open packs once across repos */
34
- git_strmap *git__pack_cache = NULL;
35
-
36
- /**
37
- * Run under mwindow lock
38
- */
39
- int git_mwindow_files_init(void)
40
- {
41
- if (git__pack_cache)
42
- return 0;
43
-
44
- return git_strmap_alloc(&git__pack_cache);
45
- }
46
-
47
- void git_mwindow_files_free(void)
48
- {
49
- git_strmap *tmp = git__pack_cache;
50
-
51
- git__pack_cache = NULL;
52
- git_strmap_free(tmp);
53
- }
54
-
55
- int git_mwindow_get_pack(struct git_pack_file **out, const char *path)
56
- {
57
- int error;
58
- char *packname;
59
- git_strmap_iter pos;
60
- struct git_pack_file *pack;
61
-
62
- if ((error = git_packfile__name(&packname, path)) < 0)
63
- return error;
64
-
65
- if (git_mutex_lock(&git__mwindow_mutex) < 0) {
66
- giterr_set(GITERR_OS, "failed to lock mwindow mutex");
67
- return -1;
68
- }
69
-
70
- if (git_mwindow_files_init() < 0) {
71
- git_mutex_unlock(&git__mwindow_mutex);
72
- git__free(packname);
73
- return -1;
74
- }
75
-
76
- pos = git_strmap_lookup_index(git__pack_cache, packname);
77
- git__free(packname);
78
-
79
- if (git_strmap_valid_index(git__pack_cache, pos)) {
80
- pack = git_strmap_value_at(git__pack_cache, pos);
81
- git_atomic_inc(&pack->refcount);
82
-
83
- git_mutex_unlock(&git__mwindow_mutex);
84
- *out = pack;
85
- return 0;
86
- }
87
-
88
- /* If we didn't find it, we need to create it */
89
- if ((error = git_packfile_alloc(&pack, path)) < 0) {
90
- git_mutex_unlock(&git__mwindow_mutex);
91
- return error;
92
- }
93
-
94
- git_atomic_inc(&pack->refcount);
95
-
96
- git_strmap_insert(git__pack_cache, pack->pack_name, pack, error);
97
- git_mutex_unlock(&git__mwindow_mutex);
98
-
99
- if (error < 0) {
100
- git_packfile_free(pack);
101
- return -1;
102
- }
103
-
104
- *out = pack;
105
- return 0;
106
- }
107
-
108
- void git_mwindow_put_pack(struct git_pack_file *pack)
109
- {
110
- int count;
111
- git_strmap_iter pos;
112
-
113
- if (git_mutex_lock(&git__mwindow_mutex) < 0)
114
- return;
115
-
116
- /* put before get would be a corrupted state */
117
- assert(git__pack_cache);
118
-
119
- pos = git_strmap_lookup_index(git__pack_cache, pack->pack_name);
120
- /* if we cannot find it, the state is corrupted */
121
- assert(git_strmap_valid_index(git__pack_cache, pos));
122
-
123
- count = git_atomic_dec(&pack->refcount);
124
- if (count == 0) {
125
- git_strmap_delete_at(git__pack_cache, pos);
126
- git_packfile_free(pack);
127
- }
128
-
129
- git_mutex_unlock(&git__mwindow_mutex);
130
- return;
131
- }
132
-
133
- void git_mwindow_free_all(git_mwindow_file *mwf)
134
- {
135
- if (git_mutex_lock(&git__mwindow_mutex)) {
136
- giterr_set(GITERR_THREAD, "unable to lock mwindow mutex");
137
- return;
138
- }
139
-
140
- git_mwindow_free_all_locked(mwf);
141
-
142
- git_mutex_unlock(&git__mwindow_mutex);
143
- }
144
-
145
29
  /*
146
30
  * Free all the windows in a sequence, typically because we're done
147
31
  * with the file
148
32
  */
149
- void git_mwindow_free_all_locked(git_mwindow_file *mwf)
33
+ void git_mwindow_free_all(git_mwindow_file *mwf)
150
34
  {
151
35
  git_mwindow_ctl *ctl = &mem_ctl;
152
36
  size_t i;
153
37
 
38
+ if (git_mutex_lock(&git__mwindow_mutex)) {
39
+ giterr_set(GITERR_THREAD, "unable to lock mwindow mutex");
40
+ return;
41
+ }
42
+
154
43
  /*
155
44
  * Remove these windows from the global list
156
45
  */
@@ -178,6 +67,8 @@ void git_mwindow_free_all_locked(git_mwindow_file *mwf)
178
67
  mwf->windows = w->next;
179
68
  git__free(w);
180
69
  }
70
+
71
+ git_mutex_unlock(&git__mwindow_mutex);
181
72
  }
182
73
 
183
74
  /*
@@ -36,18 +36,10 @@ typedef struct git_mwindow_ctl {
36
36
  } git_mwindow_ctl;
37
37
 
38
38
  int git_mwindow_contains(git_mwindow *win, git_off_t offset);
39
- void git_mwindow_free_all(git_mwindow_file *mwf); /* locks */
40
- void git_mwindow_free_all_locked(git_mwindow_file *mwf); /* run under lock */
39
+ void git_mwindow_free_all(git_mwindow_file *mwf);
41
40
  unsigned char *git_mwindow_open(git_mwindow_file *mwf, git_mwindow **cursor, git_off_t offset, size_t extra, unsigned int *left);
42
41
  int git_mwindow_file_register(git_mwindow_file *mwf);
43
42
  void git_mwindow_file_deregister(git_mwindow_file *mwf);
44
43
  void git_mwindow_close(git_mwindow **w_cursor);
45
44
 
46
- int git_mwindow_files_init(void);
47
- void git_mwindow_files_free(void);
48
-
49
- struct git_pack_file; /* just declaration to avoid cyclical includes */
50
- int git_mwindow_get_pack(struct git_pack_file **out, const char *path);
51
- void git_mwindow_put_pack(struct git_pack_file *pack);
52
-
53
45
  #endif
@@ -460,7 +460,7 @@ int gitno_connect(gitno_socket *s_out, const char *host, const char *port, int f
460
460
  hints.ai_socktype = SOCK_STREAM;
461
461
  hints.ai_family = AF_UNSPEC;
462
462
 
463
- if ((ret = p_getaddrinfo(host, port, &hints, &info)) < 0) {
463
+ if ((ret = p_getaddrinfo(host, port, &hints, &info)) != 0) {
464
464
  giterr_set(GITERR_NET,
465
465
  "Failed to resolve address for %s: %s", host, p_gai_strerror(ret));
466
466
  return -1;
@@ -717,6 +717,9 @@ int gitno_extract_url_parts(
717
717
  if (u.field_set & (1 << UF_PATH)) {
718
718
  *path = git__substrdup(_path, u.field_data[UF_PATH].len);
719
719
  GITERR_CHECK_ALLOC(*path);
720
+ } else {
721
+ giterr_set(GITERR_NET, "invalid url, missing path");
722
+ return GIT_EINVALIDSPEC;
720
723
  }
721
724
 
722
725
  if (u.field_set & (1 << UF_USERINFO)) {
@@ -210,7 +210,7 @@ static int packfile_load__cb(void *data, git_buf *path)
210
210
  return 0;
211
211
  }
212
212
 
213
- error = git_mwindow_get_pack(&pack, path->ptr);
213
+ error = git_packfile_alloc(&pack, path->ptr);
214
214
 
215
215
  /* ignore missing .pack file as git does */
216
216
  if (error == GIT_ENOTFOUND) {
@@ -605,7 +605,7 @@ static void pack_backend__free(git_odb_backend *_backend)
605
605
 
606
606
  for (i = 0; i < backend->packs.length; ++i) {
607
607
  struct git_pack_file *p = git_vector_get(&backend->packs, i);
608
- git_mwindow_put_pack(p);
608
+ git_packfile_free(p);
609
609
  }
610
610
 
611
611
  git_vector_free(&backend->packs);
@@ -647,7 +647,7 @@ int git_odb_backend_one_pack(git_odb_backend **backend_out, const char *idx)
647
647
  if (pack_backend__alloc(&backend, 1) < 0)
648
648
  return -1;
649
649
 
650
- if (git_mwindow_get_pack(&packfile, idx) < 0 ||
650
+ if (git_packfile_alloc(&packfile, idx) < 0 ||
651
651
  git_vector_insert(&backend->packs, packfile) < 0)
652
652
  {
653
653
  pack_backend__free((git_odb_backend *)backend);
@@ -664,9 +664,6 @@ int git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir)
664
664
  struct pack_backend *backend = NULL;
665
665
  git_buf path = GIT_BUF_INIT;
666
666
 
667
- if (git_mwindow_files_init() < 0)
668
- return -1;
669
-
670
667
  if (pack_backend__alloc(&backend, 8) < 0)
671
668
  return -1;
672
669
 
@@ -620,7 +620,7 @@ int git_packfile_unpack(
620
620
  struct pack_chain_elem *elem = NULL, *stack;
621
621
  git_pack_cache_entry *cached = NULL;
622
622
  struct pack_chain_elem small_stack[SMALL_STACK_SIZE];
623
- size_t stack_size, elem_pos;
623
+ size_t stack_size = 0, elem_pos;
624
624
  git_otype base_type;
625
625
 
626
626
  /*
@@ -744,7 +744,7 @@ cleanup:
744
744
  git__free(obj->data);
745
745
 
746
746
  if (elem)
747
- *obj_offset = elem->offset;
747
+ *obj_offset = curpos;
748
748
 
749
749
  git_array_clear(chain);
750
750
  return error;
@@ -968,10 +968,10 @@ void git_packfile_free(struct git_pack_file *p)
968
968
 
969
969
  cache_free(&p->bases);
970
970
 
971
- if (p->mwf.fd >= 0) {
972
- git_mwindow_free_all_locked(&p->mwf);
971
+ git_mwindow_free_all(&p->mwf);
972
+
973
+ if (p->mwf.fd >= 0)
973
974
  p_close(p->mwf.fd);
974
- }
975
975
 
976
976
  pack_index_free(p);
977
977
 
@@ -1063,23 +1063,6 @@ cleanup:
1063
1063
  return -1;
1064
1064
  }
1065
1065
 
1066
- int git_packfile__name(char **out, const char *path)
1067
- {
1068
- size_t path_len;
1069
- git_buf buf = GIT_BUF_INIT;
1070
-
1071
- path_len = strlen(path);
1072
-
1073
- if (path_len < strlen(".idx"))
1074
- return git_odb__error_notfound("invalid packfile path", NULL);
1075
-
1076
- if (git_buf_printf(&buf, "%.*s.pack", (int)(path_len - strlen(".idx")), path) < 0)
1077
- return -1;
1078
-
1079
- *out = git_buf_detach(&buf);
1080
- return 0;
1081
- }
1082
-
1083
1066
  int git_packfile_alloc(struct git_pack_file **pack_out, const char *path)
1084
1067
  {
1085
1068
  struct stat st;
@@ -90,7 +90,6 @@ struct git_pack_file {
90
90
  git_mwindow_file mwf;
91
91
  git_map index_map;
92
92
  git_mutex lock; /* protect updates to mwf and index_map */
93
- git_atomic refcount;
94
93
 
95
94
  uint32_t num_objects;
96
95
  uint32_t num_bad_objects;
@@ -124,8 +123,6 @@ typedef struct git_packfile_stream {
124
123
 
125
124
  size_t git_packfile__object_header(unsigned char *hdr, size_t size, git_otype type);
126
125
 
127
- int git_packfile__name(char **out, const char *path);
128
-
129
126
  int git_packfile_unpack_header(
130
127
  size_t *size_p,
131
128
  git_otype *type_p,
@@ -494,23 +494,33 @@ bool git_path_is_empty_dir(const char *path)
494
494
  WIN32_FIND_DATAW findData;
495
495
  HANDLE hFind = FindFirstFileW(filter_w, &findData);
496
496
 
497
+ /* FindFirstFile will fail if there are no children to the given
498
+ * path, which can happen if the given path is a file (and obviously
499
+ * has no children) or if the given path is an empty mount point.
500
+ * (Most directories have at least directory entries '.' and '..',
501
+ * but ridiculously another volume mounted in another drive letter's
502
+ * path space do not, and thus have nothing to enumerate.) If
503
+ * FindFirstFile fails, check if this is a directory-like thing
504
+ * (a mount point).
505
+ */
506
+ if (hFind == INVALID_HANDLE_VALUE)
507
+ return git_path_isdir(path);
508
+
497
509
  /* If the find handle was created successfully, then it's a directory */
498
- if (hFind != INVALID_HANDLE_VALUE) {
499
- empty = true;
500
-
501
- do {
502
- /* Allow the enumeration to return . and .. and still be considered
503
- * empty. In the special case of drive roots (i.e. C:\) where . and
504
- * .. do not occur, we can still consider the path to be an empty
505
- * directory if there's nothing there. */
506
- if (!git_path_is_dot_or_dotdotW(findData.cFileName)) {
507
- empty = false;
508
- break;
509
- }
510
- } while (FindNextFileW(hFind, &findData));
511
-
512
- FindClose(hFind);
513
- }
510
+ empty = true;
511
+
512
+ do {
513
+ /* Allow the enumeration to return . and .. and still be considered
514
+ * empty. In the special case of drive roots (i.e. C:\) where . and
515
+ * .. do not occur, we can still consider the path to be an empty
516
+ * directory if there's nothing there. */
517
+ if (!git_path_is_dot_or_dotdotW(findData.cFileName)) {
518
+ empty = false;
519
+ break;
520
+ }
521
+ } while (FindNextFileW(hFind, &findData));
522
+
523
+ FindClose(hFind);
514
524
  }
515
525
 
516
526
  return empty;
@@ -7,7 +7,7 @@ struct git_pool_page {
7
7
  git_pool_page *next;
8
8
  uint32_t size;
9
9
  uint32_t avail;
10
- char data[GIT_FLEX_ARRAY];
10
+ GIT_ALIGN(char data[GIT_FLEX_ARRAY], 8);
11
11
  };
12
12
 
13
13
  struct pool_freelist {
@@ -146,7 +146,7 @@ GIT_INLINE(void) pool_remove_page(
146
146
  void *git_pool_malloc(git_pool *pool, uint32_t items)
147
147
  {
148
148
  git_pool_page *scan = pool->open, *prev;
149
- uint32_t size = items * pool->item_size;
149
+ uint32_t size = ((items * pool->item_size) + 7) & ~7;
150
150
  void *ptr = NULL;
151
151
 
152
152
  pool->has_string_alloc = 0;
@@ -181,39 +181,63 @@ int git_refspec_dst_matches(const git_refspec *refspec, const char *refname)
181
181
  static int refspec_transform(
182
182
  git_buf *out, const char *from, const char *to, const char *name)
183
183
  {
184
- size_t to_len = to ? strlen(to) : 0;
185
- size_t from_len = from ? strlen(from) : 0;
186
- size_t name_len = name ? strlen(name) : 0;
184
+ const char *from_star, *to_star;
185
+ const char *name_slash, *from_slash;
186
+ size_t replacement_len, star_offset;
187
187
 
188
188
  git_buf_sanitize(out);
189
+ git_buf_clear(out);
189
190
 
190
- if (git_buf_set(out, to, to_len) < 0)
191
- return -1;
191
+ /*
192
+ * There are two parts to each side of a refspec, the bit
193
+ * before the star and the bit after it. The star can be in
194
+ * the middle of the pattern, so we need to look at each bit
195
+ * individually.
196
+ */
197
+ from_star = strchr(from, '*');
198
+ to_star = strchr(to, '*');
192
199
 
193
- if (to_len > 0) {
194
- /* No '*' at the end of 'to' means that refspec is mapped to one
195
- * specific branch, so no actual transformation is needed.
196
- */
197
- if (out->ptr[to_len - 1] != '*')
198
- return 0;
199
- git_buf_shorten(out, 1); /* remove trailing '*' copied from 'to' */
200
- }
200
+ assert(from_star && to_star);
201
+
202
+ /* star offset, both in 'from' and in 'name' */
203
+ star_offset = from_star - from;
204
+
205
+ /* the first half is copied over */
206
+ git_buf_put(out, to, to_star - to);
207
+
208
+ /* then we copy over the replacement, from the star's offset to the next slash in 'name' */
209
+ name_slash = strchr(name + star_offset, '/');
210
+ if (!name_slash)
211
+ name_slash = strrchr(name, '\0');
201
212
 
202
- if (from_len > 0) /* ignore trailing '*' from 'from' */
203
- from_len--;
204
- if (from_len > name_len)
205
- from_len = name_len;
213
+ /* if there is no slash after the star in 'from', we want to copy everything over */
214
+ from_slash = strchr(from + star_offset, '/');
215
+ if (!from_slash)
216
+ name_slash = strrchr(name, '\0');
206
217
 
207
- return git_buf_put(out, name + from_len, name_len - from_len);
218
+ replacement_len = (name_slash - name) - star_offset;
219
+ git_buf_put(out, name + star_offset, replacement_len);
220
+
221
+ return git_buf_puts(out, to_star + 1);
208
222
  }
209
223
 
210
224
  int git_refspec_transform(git_buf *out, const git_refspec *spec, const char *name)
211
225
  {
226
+ git_buf_sanitize(out);
227
+
228
+ if (!spec->pattern)
229
+ return git_buf_puts(out, spec->dst);
230
+
212
231
  return refspec_transform(out, spec->src, spec->dst, name);
213
232
  }
214
233
 
215
234
  int git_refspec_rtransform(git_buf *out, const git_refspec *spec, const char *name)
216
235
  {
236
+ git_buf_sanitize(out);
237
+
238
+ if (!spec->pattern)
239
+ return git_buf_puts(out, spec->src);
240
+
217
241
  return refspec_transform(out, spec->dst, spec->src, name);
218
242
  }
219
243
 
@@ -691,6 +691,11 @@ int git_remote_ls(const git_remote_head ***out, size_t *size, git_remote *remote
691
691
  {
692
692
  assert(remote);
693
693
 
694
+ if (!remote->transport) {
695
+ giterr_set(GITERR_NET, "No transport bound to this remote");
696
+ return -1;
697
+ }
698
+
694
699
  return remote->transport->ls(out, size, remote->transport);
695
700
  }
696
701
 
@@ -1052,16 +1057,20 @@ static int update_tips_for_spec(
1052
1057
  if (autotag && !git_odb_exists(odb, &head->oid))
1053
1058
  continue;
1054
1059
 
1055
- if (git_vector_insert(&update_heads, head) < 0)
1060
+ if (!autotag && git_vector_insert(&update_heads, head) < 0)
1056
1061
  goto on_error;
1057
1062
 
1058
1063
  error = git_reference_name_to_id(&old, remote->repo, refname.ptr);
1059
1064
  if (error < 0 && error != GIT_ENOTFOUND)
1060
1065
  goto on_error;
1061
1066
 
1062
- if (error == GIT_ENOTFOUND)
1067
+ if (error == GIT_ENOTFOUND) {
1063
1068
  memset(&old, 0, GIT_OID_RAWSZ);
1064
1069
 
1070
+ if (autotag && git_vector_insert(&update_heads, head) < 0)
1071
+ goto on_error;
1072
+ }
1073
+
1065
1074
  if (!git_oid__cmp(&old, &head->oid))
1066
1075
  continue;
1067
1076
 
@@ -1932,6 +1941,8 @@ int git_remote_default_branch(git_buf *out, git_remote *remote)
1932
1941
  size_t heads_len, i;
1933
1942
  int error;
1934
1943
 
1944
+ assert(out);
1945
+
1935
1946
  if ((error = git_remote_ls(&heads, &heads_len, remote)) < 0)
1936
1947
  return error;
1937
1948
 
@@ -1551,8 +1551,10 @@ int git_repository_head_unborn(git_repository *repo)
1551
1551
  error = git_repository_head(&ref, repo);
1552
1552
  git_reference_free(ref);
1553
1553
 
1554
- if (error == GIT_EUNBORNBRANCH)
1554
+ if (error == GIT_EUNBORNBRANCH) {
1555
+ giterr_clear();
1555
1556
  return 1;
1557
+ }
1556
1558
 
1557
1559
  if (error < 0)
1558
1560
  return -1;
@@ -48,9 +48,6 @@ static int mark_uninteresting(git_revwalk *walk, git_commit_list_node *commit)
48
48
 
49
49
  assert(commit);
50
50
 
51
- git_array_init_to_size(pending, 2);
52
- GITERR_CHECK_ARRAY(pending);
53
-
54
51
  do {
55
52
  commit->uninteresting = 1;
56
53
 
@@ -232,7 +232,8 @@ static int build_untracked_tree(
232
232
  }
233
233
 
234
234
  if (flags & GIT_STASH_INCLUDE_IGNORED) {
235
- opts.flags |= GIT_DIFF_INCLUDE_IGNORED;
235
+ opts.flags |= GIT_DIFF_INCLUDE_IGNORED |
236
+ GIT_DIFF_RECURSE_IGNORED_DIRS;
236
237
  data.include_ignored = true;
237
238
  }
238
239
 
@@ -447,10 +448,11 @@ static int ensure_there_are_changes_to_stash(
447
448
 
448
449
  if (include_untracked_files)
449
450
  opts.flags |= GIT_STATUS_OPT_INCLUDE_UNTRACKED |
450
- GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS;
451
+ GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS;
451
452
 
452
453
  if (include_ignored_files)
453
- opts.flags |= GIT_STATUS_OPT_INCLUDE_IGNORED;
454
+ opts.flags |= GIT_STATUS_OPT_INCLUDE_IGNORED |
455
+ GIT_STATUS_OPT_RECURSE_IGNORED_DIRS;
454
456
 
455
457
  error = git_status_foreach_ext(repo, &opts, is_dirty_cb, NULL);
456
458
 
@@ -406,8 +406,9 @@ int git_tag_delete(git_repository *repo, const char *tag_name)
406
406
  if (error < 0)
407
407
  return error;
408
408
 
409
- if ((error = git_reference_delete(tag_ref)) == 0)
410
- git_reference_free(tag_ref);
409
+ error = git_reference_delete(tag_ref);
410
+
411
+ git_reference_free(tag_ref);
411
412
 
412
413
  return error;
413
414
  }
@@ -537,7 +537,23 @@ replay:
537
537
  }
538
538
 
539
539
  while (!*bytes_read && !t->parse_finished) {
540
- t->parse_buffer.offset = 0;
540
+ size_t data_offset;
541
+
542
+ /*
543
+ * Make the parse_buffer think it's as full of data as
544
+ * the buffer, so it won't try to recv more data than
545
+ * we can put into it.
546
+ *
547
+ * data_offset is the actual data offset from which we
548
+ * should tell the parser to start reading.
549
+ */
550
+ if (buf_size >= t->parse_buffer.len) {
551
+ t->parse_buffer.offset = 0;
552
+ } else {
553
+ t->parse_buffer.offset = t->parse_buffer.len - buf_size;
554
+ }
555
+
556
+ data_offset = t->parse_buffer.offset;
541
557
 
542
558
  if (gitno_recv(&t->parse_buffer) < 0)
543
559
  return -1;
@@ -558,8 +574,8 @@ replay:
558
574
 
559
575
  bytes_parsed = http_parser_execute(&t->parser,
560
576
  &t->settings,
561
- t->parse_buffer.data,
562
- t->parse_buffer.offset);
577
+ t->parse_buffer.data + data_offset,
578
+ t->parse_buffer.offset - data_offset);
563
579
 
564
580
  t->parser.data = NULL;
565
581
 
@@ -577,7 +593,7 @@ replay:
577
593
  if (t->parse_error < 0)
578
594
  return -1;
579
595
 
580
- if (bytes_parsed != t->parse_buffer.offset) {
596
+ if (bytes_parsed != t->parse_buffer.offset - data_offset) {
581
597
  giterr_set(GITERR_NET,
582
598
  "HTTP parser error: %s",
583
599
  http_errno_description((enum http_errno)t->parser.http_errno));
@@ -5,6 +5,10 @@
5
5
  * a Linking Exception. For full terms see the included COPYING file.
6
6
  */
7
7
 
8
+ #ifdef GIT_SSH
9
+ #include <libssh2.h>
10
+ #endif
11
+
8
12
  #include "git2.h"
9
13
  #include "buffer.h"
10
14
  #include "netops.h"
@@ -12,8 +16,6 @@
12
16
 
13
17
  #ifdef GIT_SSH
14
18
 
15
- #include <libssh2.h>
16
-
17
19
  #define OWNING_SUBTRANSPORT(s) ((ssh_subtransport *)(s)->parent.subtransport)
18
20
 
19
21
  static const char prefix_ssh[] = "ssh://";
@@ -132,11 +134,22 @@ static int ssh_stream_write(
132
134
  size_t len)
133
135
  {
134
136
  ssh_stream *s = (ssh_stream *)stream;
137
+ size_t off = 0;
138
+ ssize_t ret = 0;
135
139
 
136
140
  if (!s->sent_command && send_command(s) < 0)
137
141
  return -1;
138
142
 
139
- if (libssh2_channel_write(s->channel, buffer, len) < LIBSSH2_ERROR_NONE) {
143
+ do {
144
+ ret = libssh2_channel_write(s->channel, buffer + off, len - off);
145
+ if (ret < 0)
146
+ break;
147
+
148
+ off += ret;
149
+
150
+ } while (off < len);
151
+
152
+ if (ret < 0) {
140
153
  ssh_error(s->session, "SSH could not write data");
141
154
  return -1;
142
155
  }
@@ -274,6 +287,10 @@ static int ssh_agent_auth(LIBSSH2_SESSION *session, git_cred_ssh_key *c) {
274
287
  }
275
288
 
276
289
  shutdown:
290
+
291
+ if (rc != LIBSSH2_ERROR_NONE)
292
+ ssh_error(session, "error authenticating");
293
+
277
294
  libssh2_agent_disconnect(agent);
278
295
  libssh2_agent_free(agent);
279
296
 
@@ -287,6 +304,7 @@ static int _git_ssh_authenticate_session(
287
304
  int rc;
288
305
 
289
306
  do {
307
+ giterr_clear();
290
308
  switch (cred->credtype) {
291
309
  case GIT_CREDTYPE_USERPASS_PLAINTEXT: {
292
310
  git_cred_userpass_plaintext *c = (git_cred_userpass_plaintext *)cred;
@@ -340,7 +358,8 @@ static int _git_ssh_authenticate_session(
340
358
  } while (LIBSSH2_ERROR_EAGAIN == rc || LIBSSH2_ERROR_TIMEOUT == rc);
341
359
 
342
360
  if (rc != LIBSSH2_ERROR_NONE) {
343
- ssh_error(session, "Failed to authenticate SSH session");
361
+ if (!giterr_last())
362
+ ssh_error(session, "Failed to authenticate SSH session");
344
363
  return -1;
345
364
  }
346
365