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.
Files changed (158) hide show
  1. data/README.md +3 -3
  2. data/Rakefile +3 -1
  3. data/ext/rugged/rugged.c +30 -0
  4. data/ext/rugged/rugged.h +9 -0
  5. data/ext/rugged/rugged_branch.c +306 -0
  6. data/ext/rugged/rugged_config.c +16 -13
  7. data/ext/rugged/rugged_index.c +25 -0
  8. data/ext/rugged/rugged_object.c +6 -2
  9. data/ext/rugged/rugged_reference.c +11 -18
  10. data/ext/rugged/rugged_revwalk.c +1 -1
  11. data/lib/rugged.rb +1 -0
  12. data/lib/rugged/branch.rb +28 -0
  13. data/lib/rugged/commit.rb +5 -5
  14. data/lib/rugged/repository.rb +32 -7
  15. data/lib/rugged/tag.rb +5 -1
  16. data/lib/rugged/version.rb +1 -1
  17. data/test/branch_test.rb +227 -0
  18. data/test/config_test.rb +1 -1
  19. data/test/fixtures/testrepo.git/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 +0 -0
  20. data/test/fixtures/testrepo.git/objects/a3/e05719b428a2d0ed7a55c4ce53dcc5768c6d5e +0 -0
  21. data/test/index_test.rb +31 -0
  22. data/test/index_test.rb~ +218 -0
  23. data/test/lib_test.rb +22 -0
  24. data/test/reference_test.rb +5 -3
  25. data/vendor/libgit2/Makefile.embed +1 -1
  26. data/vendor/libgit2/include/git2.h +1 -0
  27. data/vendor/libgit2/include/git2/branch.h +17 -13
  28. data/vendor/libgit2/include/git2/checkout.h +83 -22
  29. data/vendor/libgit2/include/git2/clone.h +6 -3
  30. data/vendor/libgit2/include/git2/common.h +1 -8
  31. data/vendor/libgit2/include/git2/config.h +185 -26
  32. data/vendor/libgit2/include/git2/diff.h +229 -17
  33. data/vendor/libgit2/include/git2/errors.h +39 -1
  34. data/vendor/libgit2/include/git2/ignore.h +6 -3
  35. data/vendor/libgit2/include/git2/indexer.h +1 -0
  36. data/vendor/libgit2/include/git2/merge.h +1 -1
  37. data/vendor/libgit2/include/git2/object.h +7 -4
  38. data/vendor/libgit2/include/git2/odb.h +4 -2
  39. data/vendor/libgit2/include/git2/odb_backend.h +6 -0
  40. data/vendor/libgit2/include/git2/oid.h +2 -0
  41. data/vendor/libgit2/include/git2/pack.h +89 -0
  42. data/vendor/libgit2/include/git2/refs.h +88 -0
  43. data/vendor/libgit2/include/git2/refspec.h +0 -8
  44. data/vendor/libgit2/include/git2/remote.h +34 -1
  45. data/vendor/libgit2/include/git2/repository.h +238 -6
  46. data/vendor/libgit2/include/git2/reset.h +4 -1
  47. data/vendor/libgit2/include/git2/revwalk.h +1 -1
  48. data/vendor/libgit2/include/git2/status.h +19 -14
  49. data/vendor/libgit2/include/git2/strarray.h +54 -0
  50. data/vendor/libgit2/include/git2/submodule.h +451 -45
  51. data/vendor/libgit2/include/git2/tag.h +16 -0
  52. data/vendor/libgit2/include/git2/tree.h +2 -2
  53. data/vendor/libgit2/include/git2/types.h +4 -0
  54. data/vendor/libgit2/src/amiga/map.c +4 -7
  55. data/vendor/libgit2/src/attr.c +21 -13
  56. data/vendor/libgit2/src/attr.h +3 -1
  57. data/vendor/libgit2/src/attr_file.c +14 -14
  58. data/vendor/libgit2/src/attr_file.h +6 -5
  59. data/vendor/libgit2/src/blob.c +22 -12
  60. data/vendor/libgit2/src/branch.c +62 -66
  61. data/vendor/libgit2/src/buffer.c +63 -14
  62. data/vendor/libgit2/src/buffer.h +4 -0
  63. data/vendor/libgit2/src/cache.c +5 -4
  64. data/vendor/libgit2/src/checkout.c +381 -159
  65. data/vendor/libgit2/src/clone.c +221 -94
  66. data/vendor/libgit2/src/common.h +13 -3
  67. data/vendor/libgit2/src/compress.c +53 -0
  68. data/vendor/libgit2/src/compress.h +16 -0
  69. data/vendor/libgit2/src/config.c +380 -175
  70. data/vendor/libgit2/src/config.h +2 -5
  71. data/vendor/libgit2/src/config_file.c +63 -46
  72. data/vendor/libgit2/src/config_file.h +16 -4
  73. data/vendor/libgit2/src/crlf.c +4 -3
  74. data/vendor/libgit2/src/delta.c +491 -0
  75. data/vendor/libgit2/src/delta.h +112 -0
  76. data/vendor/libgit2/src/diff.c +310 -67
  77. data/vendor/libgit2/src/diff.h +10 -1
  78. data/vendor/libgit2/src/diff_output.c +1030 -337
  79. data/vendor/libgit2/src/diff_output.h +86 -0
  80. data/vendor/libgit2/src/errors.c +10 -1
  81. data/vendor/libgit2/src/fetch.c +108 -24
  82. data/vendor/libgit2/src/filebuf.c +8 -2
  83. data/vendor/libgit2/src/fileops.c +342 -177
  84. data/vendor/libgit2/src/fileops.h +84 -7
  85. data/vendor/libgit2/src/filter.c +0 -35
  86. data/vendor/libgit2/src/filter.h +0 -12
  87. data/vendor/libgit2/src/{compat/fnmatch.c → fnmatch.c} +16 -4
  88. data/vendor/libgit2/src/{compat/fnmatch.h → fnmatch.h} +4 -3
  89. data/vendor/libgit2/src/global.c +4 -0
  90. data/vendor/libgit2/src/ignore.c +122 -23
  91. data/vendor/libgit2/src/ignore.h +1 -0
  92. data/vendor/libgit2/src/index.c +56 -10
  93. data/vendor/libgit2/src/index.h +2 -0
  94. data/vendor/libgit2/src/indexer.c +8 -9
  95. data/vendor/libgit2/src/iterator.c +244 -31
  96. data/vendor/libgit2/src/iterator.h +30 -1
  97. data/vendor/libgit2/src/message.c +1 -1
  98. data/vendor/libgit2/src/netops.c +44 -4
  99. data/vendor/libgit2/src/object.c +80 -69
  100. data/vendor/libgit2/src/object.h +39 -0
  101. data/vendor/libgit2/src/odb.c +79 -15
  102. data/vendor/libgit2/src/odb.h +20 -5
  103. data/vendor/libgit2/src/odb_pack.c +65 -33
  104. data/vendor/libgit2/src/oid.c +0 -3
  105. data/vendor/libgit2/src/pack-objects.c +1315 -0
  106. data/vendor/libgit2/src/pack-objects.h +87 -0
  107. data/vendor/libgit2/src/pack.c +36 -12
  108. data/vendor/libgit2/src/pack.h +1 -0
  109. data/vendor/libgit2/src/path.c +42 -9
  110. data/vendor/libgit2/src/path.h +14 -0
  111. data/vendor/libgit2/src/pkt.c +52 -2
  112. data/vendor/libgit2/src/pkt.h +10 -0
  113. data/vendor/libgit2/src/pool.h +11 -0
  114. data/vendor/libgit2/src/posix.h +8 -0
  115. data/vendor/libgit2/src/protocol.c +24 -2
  116. data/vendor/libgit2/src/protocol.h +4 -0
  117. data/vendor/libgit2/src/reflog.c +1 -1
  118. data/vendor/libgit2/src/refs.c +292 -124
  119. data/vendor/libgit2/src/refs.h +4 -2
  120. data/vendor/libgit2/src/refspec.c +117 -19
  121. data/vendor/libgit2/src/refspec.h +19 -0
  122. data/vendor/libgit2/src/remote.c +152 -48
  123. data/vendor/libgit2/src/remote.h +4 -1
  124. data/vendor/libgit2/src/repo_template.h +58 -0
  125. data/vendor/libgit2/src/repository.c +594 -179
  126. data/vendor/libgit2/src/repository.h +23 -22
  127. data/vendor/libgit2/src/reset.c +71 -29
  128. data/vendor/libgit2/src/revparse.c +26 -17
  129. data/vendor/libgit2/src/revwalk.c +36 -19
  130. data/vendor/libgit2/src/sha1.h +7 -0
  131. data/vendor/libgit2/src/{sha1.c → sha1/sha1.c} +0 -0
  132. data/vendor/libgit2/src/signature.c +12 -10
  133. data/vendor/libgit2/src/status.c +52 -6
  134. data/vendor/libgit2/src/submodule.c +1363 -255
  135. data/vendor/libgit2/src/submodule.h +102 -0
  136. data/vendor/libgit2/src/tag.c +42 -26
  137. data/vendor/libgit2/src/thread-utils.h +7 -7
  138. data/vendor/libgit2/src/transport.h +15 -1
  139. data/vendor/libgit2/src/transports/git.c +1 -1
  140. data/vendor/libgit2/src/transports/http.c +197 -36
  141. data/vendor/libgit2/src/tree.c +3 -3
  142. data/vendor/libgit2/src/unix/map.c +2 -0
  143. data/vendor/libgit2/src/unix/posix.h +1 -8
  144. data/vendor/libgit2/src/util.c +6 -1
  145. data/vendor/libgit2/src/util.h +7 -0
  146. data/vendor/libgit2/src/vector.c +16 -0
  147. data/vendor/libgit2/src/vector.h +1 -0
  148. data/vendor/libgit2/src/win32/dir.c +8 -21
  149. data/vendor/libgit2/src/win32/findfile.c +149 -0
  150. data/vendor/libgit2/src/win32/findfile.h +23 -0
  151. data/vendor/libgit2/src/win32/posix.h +3 -7
  152. data/vendor/libgit2/src/win32/posix_w32.c +44 -102
  153. data/vendor/libgit2/src/win32/pthread.c +68 -0
  154. data/vendor/libgit2/src/win32/pthread.h +7 -0
  155. data/vendor/libgit2/src/win32/utf-conv.c +60 -71
  156. data/vendor/libgit2/src/win32/utf-conv.h +4 -3
  157. metadata +70 -71
  158. data/vendor/libgit2/include/git2/windows.h +0 -59
@@ -11,6 +11,7 @@
11
11
  #include "types.h"
12
12
  #include "oid.h"
13
13
  #include "object.h"
14
+ #include "strarray.h"
14
15
 
15
16
  /**
16
17
  * @file git2/tag.h
@@ -277,6 +278,21 @@ GIT_EXTERN(int) git_tag_list_match(
277
278
  const char *pattern,
278
279
  git_repository *repo);
279
280
 
281
+
282
+ typedef int (*git_tag_foreach_cb)(const char *name, git_oid *oid, void *data);
283
+ /**
284
+ * Call callback `cb' for each tag in the repository
285
+ *
286
+ * @param repo Repository
287
+ * @param cb Callback function
288
+ * @param cb_data Pointer to callback data (optional)
289
+ */
290
+ GIT_EXTERN(int) git_tag_foreach(
291
+ git_repository *repo,
292
+ git_tag_foreach_cb cb,
293
+ void *cb_data);
294
+
295
+
280
296
  /**
281
297
  * Recursively peel a tag until a non tag git_object
282
298
  * is met
@@ -100,7 +100,7 @@ GIT_EXTERN(git_tree_entry *) git_tree_entry_dup(const git_tree_entry *entry);
100
100
  * @param tree a previously loaded tree.
101
101
  * @return object identity for the tree.
102
102
  */
103
- GIT_EXTERN(const git_oid *) git_tree_id(git_tree *tree);
103
+ GIT_EXTERN(const git_oid *) git_tree_id(const git_tree *tree);
104
104
 
105
105
  /**
106
106
  * Get the number of entries listed in a tree
@@ -108,7 +108,7 @@ GIT_EXTERN(const git_oid *) git_tree_id(git_tree *tree);
108
108
  * @param tree a previously loaded tree.
109
109
  * @return the number of entries in the tree
110
110
  */
111
- GIT_EXTERN(unsigned int) git_tree_entrycount(git_tree *tree);
111
+ GIT_EXTERN(unsigned int) git_tree_entrycount(const git_tree *tree);
112
112
 
113
113
  /**
114
114
  * Lookup a tree entry by its filename
@@ -137,6 +137,9 @@ typedef struct git_reflog git_reflog;
137
137
  /** Representation of a git note */
138
138
  typedef struct git_note git_note;
139
139
 
140
+ /** Representation of a git packbuilder */
141
+ typedef struct git_packbuilder git_packbuilder;
142
+
140
143
  /** Time in a signature */
141
144
  typedef struct git_time {
142
145
  git_time_t time; /** time in seconds from epoch */
@@ -173,6 +176,7 @@ typedef enum {
173
176
  typedef enum {
174
177
  GIT_RESET_SOFT = 1,
175
178
  GIT_RESET_MIXED = 2,
179
+ GIT_RESET_HARD = 3,
176
180
  } git_reset_type;
177
181
 
178
182
  /** Valid modes for index and tree entries. */
@@ -24,18 +24,15 @@ int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, git_off_t offs
24
24
  return -1;
25
25
  }
26
26
 
27
- if((out->data = malloc(len))) {
28
- p_lseek(fd, offset, SEEK_SET);
29
- p_read(fd, out->data, len);
30
- }
27
+ out->data = malloc(len);
28
+ GITERR_CHECK_ALLOC(out->data);
31
29
 
32
- if (!out->data || (out->data == MAP_FAILED)) {
33
- giterr_set(GITERR_OS, "Failed to mmap. Could not write data");
30
+ if (p_lseek(fd, offset, SEEK_SET) < 0 || p_read(fd, out->data, len) != len)
31
+ giterr_set(GITERR_OS, "mmap emulation failed");
34
32
  return -1;
35
33
  }
36
34
 
37
35
  out->len = len;
38
-
39
36
  return 0;
40
37
  }
41
38
 
@@ -188,6 +188,7 @@ int git_attr_foreach(
188
188
 
189
189
  error = callback(assign->name, assign->value, payload);
190
190
  if (error) {
191
+ giterr_clear();
191
192
  error = GIT_EUSER;
192
193
  goto cleanup;
193
194
  }
@@ -375,6 +376,7 @@ int git_attr_cache__push_file(
375
376
  const char *filename,
376
377
  git_attr_file_source source,
377
378
  git_attr_file_parser parse,
379
+ void* parsedata,
378
380
  git_vector *stack)
379
381
  {
380
382
  int error = 0;
@@ -435,7 +437,7 @@ int git_attr_cache__push_file(
435
437
  goto finish;
436
438
  }
437
439
 
438
- if (parse && (error = parse(repo, content, file)) < 0)
440
+ if (parse && (error = parse(repo, parsedata, content, file)) < 0)
439
441
  goto finish;
440
442
 
441
443
  git_strmap_insert(cache->files, file->key, file, error); //-V595
@@ -467,7 +469,7 @@ finish:
467
469
  }
468
470
 
469
471
  #define push_attr_file(R,S,B,F) \
470
- git_attr_cache__push_file((R),(B),(F),GIT_ATTR_FILE_FROM_FILE,git_attr_file__parse_buffer,(S))
472
+ git_attr_cache__push_file((R),(B),(F),GIT_ATTR_FILE_FROM_FILE,git_attr_file__parse_buffer,NULL,(S))
471
473
 
472
474
  typedef struct {
473
475
  git_repository *repo;
@@ -516,7 +518,7 @@ static int push_one_attr(void *ref, git_buf *path)
516
518
  for (i = 0; !error && i < n_src; ++i)
517
519
  error = git_attr_cache__push_file(
518
520
  info->repo, path->ptr, GIT_ATTR_FILE, src[i],
519
- git_attr_file__parse_buffer, info->files);
521
+ git_attr_file__parse_buffer, NULL, info->files);
520
522
 
521
523
  return error;
522
524
  }
@@ -590,6 +592,18 @@ static int collect_attr_files(
590
592
  return error;
591
593
  }
592
594
 
595
+ static char *try_global_default(const char *relpath)
596
+ {
597
+ git_buf dflt = GIT_BUF_INIT;
598
+ char *rval = NULL;
599
+
600
+ if (!git_futils_find_global_file(&dflt, relpath))
601
+ rval = git_buf_detach(&dflt);
602
+
603
+ git_buf_free(&dflt);
604
+
605
+ return rval;
606
+ }
593
607
 
594
608
  int git_attr_cache__init(git_repository *repo)
595
609
  {
@@ -607,20 +621,14 @@ int git_attr_cache__init(git_repository *repo)
607
621
  ret = git_config_get_string(&cache->cfg_attr_file, cfg, GIT_ATTR_CONFIG);
608
622
  if (ret < 0 && ret != GIT_ENOTFOUND)
609
623
  return ret;
624
+ if (ret == GIT_ENOTFOUND)
625
+ cache->cfg_attr_file = try_global_default(GIT_ATTR_CONFIG_DEFAULT);
610
626
 
611
627
  ret = git_config_get_string(&cache->cfg_excl_file, cfg, GIT_IGNORE_CONFIG);
612
628
  if (ret < 0 && ret != GIT_ENOTFOUND)
613
629
  return ret;
614
-
615
- if (ret == GIT_ENOTFOUND) {
616
- git_buf dflt = GIT_BUF_INIT;
617
-
618
- ret = git_futils_find_global_file(&dflt, GIT_IGNORE_CONFIG_DEFAULT);
619
- if (!ret)
620
- cache->cfg_excl_file = git_buf_detach(&dflt);
621
-
622
- git_buf_free(&dflt);
623
- }
630
+ if (ret == GIT_ENOTFOUND)
631
+ cache->cfg_excl_file = try_global_default(GIT_IGNORE_CONFIG_DEFAULT);
624
632
 
625
633
  giterr_clear();
626
634
 
@@ -11,6 +11,7 @@
11
11
  #include "strmap.h"
12
12
 
13
13
  #define GIT_ATTR_CONFIG "core.attributesfile"
14
+ #define GIT_ATTR_CONFIG_DEFAULT ".config/git/attributes"
14
15
  #define GIT_IGNORE_CONFIG "core.excludesfile"
15
16
  #define GIT_IGNORE_CONFIG_DEFAULT ".config/git/ignore"
16
17
 
@@ -24,7 +25,7 @@ typedef struct {
24
25
  } git_attr_cache;
25
26
 
26
27
  typedef int (*git_attr_file_parser)(
27
- git_repository *, const char *, git_attr_file *);
28
+ git_repository *, void *, const char *, git_attr_file *);
28
29
 
29
30
  extern int git_attr_cache__init(git_repository *repo);
30
31
 
@@ -40,6 +41,7 @@ extern int git_attr_cache__push_file(
40
41
  const char *filename,
41
42
  git_attr_file_source source,
42
43
  git_attr_file_parser parse,
44
+ void *parsedata, /* passed through to parse function */
43
45
  git_vector *stack);
44
46
 
45
47
  extern int git_attr_cache__internal_file(
@@ -53,13 +53,15 @@ fail:
53
53
  }
54
54
 
55
55
  int git_attr_file__parse_buffer(
56
- git_repository *repo, const char *buffer, git_attr_file *attrs)
56
+ git_repository *repo, void *parsedata, const char *buffer, git_attr_file *attrs)
57
57
  {
58
58
  int error = 0;
59
59
  const char *scan = NULL;
60
60
  char *context = NULL;
61
61
  git_attr_rule *rule = NULL;
62
62
 
63
+ GIT_UNUSED(parsedata);
64
+
63
65
  assert(buffer && attrs);
64
66
 
65
67
  scan = buffer;
@@ -123,7 +125,7 @@ int git_attr_file__new_and_load(
123
125
 
124
126
  if (!(error = git_futils_readbuffer(&content, path)))
125
127
  error = git_attr_file__parse_buffer(
126
- NULL, git_buf_cstr(&content), *attrs_ptr);
128
+ NULL, NULL, git_buf_cstr(&content), *attrs_ptr);
127
129
 
128
130
  git_buf_free(&content);
129
131
 
@@ -207,16 +209,17 @@ bool git_attr_fnmatch__match(
207
209
  const git_attr_path *path)
208
210
  {
209
211
  int fnm;
212
+ int icase_flags = (match->flags & GIT_ATTR_FNMATCH_ICASE) ? FNM_CASEFOLD : 0;
210
213
 
211
214
  if (match->flags & GIT_ATTR_FNMATCH_DIRECTORY && !path->is_dir)
212
215
  return false;
213
216
 
214
217
  if (match->flags & GIT_ATTR_FNMATCH_FULLPATH)
215
- fnm = p_fnmatch(match->pattern, path->path, FNM_PATHNAME);
218
+ fnm = p_fnmatch(match->pattern, path->path, FNM_PATHNAME | icase_flags);
216
219
  else if (path->is_dir)
217
- fnm = p_fnmatch(match->pattern, path->basename, FNM_LEADING_DIR);
220
+ fnm = p_fnmatch(match->pattern, path->basename, FNM_LEADING_DIR | icase_flags);
218
221
  else
219
- fnm = p_fnmatch(match->pattern, path->basename, 0);
222
+ fnm = p_fnmatch(match->pattern, path->basename, icase_flags);
220
223
 
221
224
  return (fnm == FNM_NOMATCH) ? false : true;
222
225
  }
@@ -250,18 +253,15 @@ git_attr_assignment *git_attr_rule__lookup_assignment(
250
253
  int git_attr_path__init(
251
254
  git_attr_path *info, const char *path, const char *base)
252
255
  {
256
+ ssize_t root;
257
+
253
258
  /* build full path as best we can */
254
259
  git_buf_init(&info->full, 0);
255
260
 
256
- if (base != NULL && git_path_root(path) < 0) {
257
- if (git_buf_joinpath(&info->full, base, path) < 0)
258
- return -1;
259
- info->path = info->full.ptr + strlen(base);
260
- } else {
261
- if (git_buf_sets(&info->full, path) < 0)
262
- return -1;
263
- info->path = info->full.ptr;
264
- }
261
+ if (git_path_join_unrooted(&info->full, path, base, &root) < 0)
262
+ return -1;
263
+
264
+ info->path = info->full.ptr + root;
265
265
 
266
266
  /* remove trailing slashes */
267
267
  while (info->full.size > 0) {
@@ -23,6 +23,7 @@
23
23
  #define GIT_ATTR_FNMATCH_IGNORE (1U << 4)
24
24
  #define GIT_ATTR_FNMATCH_HASWILD (1U << 5)
25
25
  #define GIT_ATTR_FNMATCH_ALLOWSPACE (1U << 6)
26
+ #define GIT_ATTR_FNMATCH_ICASE (1U << 7)
26
27
 
27
28
  extern const char *git_attr__true;
28
29
  extern const char *git_attr__false;
@@ -70,10 +71,10 @@ typedef struct {
70
71
  } git_attr_file;
71
72
 
72
73
  typedef struct {
73
- git_buf full;
74
- const char *path;
75
- const char *basename;
76
- int is_dir;
74
+ git_buf full;
75
+ char *path;
76
+ char *basename;
77
+ int is_dir;
77
78
  } git_attr_path;
78
79
 
79
80
  typedef enum {
@@ -96,7 +97,7 @@ extern void git_attr_file__free(git_attr_file *file);
96
97
  extern void git_attr_file__clear_rules(git_attr_file *file);
97
98
 
98
99
  extern int git_attr_file__parse_buffer(
99
- git_repository *repo, const char *buf, git_attr_file *file);
100
+ git_repository *repo, void *parsedata, const char *buf, git_attr_file *file);
100
101
 
101
102
  extern int git_attr_file__lookup_one(
102
103
  git_attr_file *file,
@@ -68,6 +68,7 @@ static int write_file_stream(
68
68
  int fd, error;
69
69
  char buffer[4096];
70
70
  git_odb_stream *stream = NULL;
71
+ ssize_t read_len = -1, written = 0;
71
72
 
72
73
  if ((error = git_odb_open_wstream(
73
74
  &stream, odb, (size_t)file_size, GIT_OBJ_BLOB)) < 0)
@@ -78,20 +79,18 @@ static int write_file_stream(
78
79
  return -1;
79
80
  }
80
81
 
81
- while (!error && file_size > 0) {
82
- ssize_t read_len = p_read(fd, buffer, sizeof(buffer));
83
-
84
- if (read_len < 0) {
85
- giterr_set(
86
- GITERR_OS, "Failed to create blob. Can't read whole file");
87
- error = -1;
88
- }
89
- else if (!(error = stream->write(stream, buffer, read_len)))
90
- file_size -= read_len;
82
+ while (!error && (read_len = p_read(fd, buffer, sizeof(buffer))) > 0) {
83
+ error = stream->write(stream, buffer, read_len);
84
+ written += read_len;
91
85
  }
92
86
 
93
87
  p_close(fd);
94
88
 
89
+ if (written != file_size || read_len < 0) {
90
+ giterr_set(GITERR_OS, "Failed to read file into stream");
91
+ error = -1;
92
+ }
93
+
95
94
  if (!error)
96
95
  error = stream->finalize_write(oid, stream);
97
96
 
@@ -212,8 +211,10 @@ int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *pat
212
211
  const char *workdir;
213
212
  int error;
214
213
 
214
+ if ((error = git_repository__ensure_not_bare(repo, "create blob from file")) < 0)
215
+ return error;
216
+
215
217
  workdir = git_repository_workdir(repo);
216
- assert(workdir); /* error to call this on bare repo */
217
218
 
218
219
  if (git_buf_joinpath(&full_path, workdir, path) < 0) {
219
220
  git_buf_free(&full_path);
@@ -254,11 +255,19 @@ int git_blob_create_fromchunks(
254
255
  int error = -1, read_bytes;
255
256
  char *content = NULL;
256
257
  git_filebuf file = GIT_FILEBUF_INIT;
258
+ git_buf path = GIT_BUF_INIT;
259
+
260
+ if (git_buf_join_n(
261
+ &path, '/', 3,
262
+ git_repository_path(repo),
263
+ GIT_OBJECTS_DIR,
264
+ "streamed") < 0)
265
+ goto cleanup;
257
266
 
258
267
  content = git__malloc(BUFFER_SIZE);
259
268
  GITERR_CHECK_ALLOC(content);
260
269
 
261
- if (git_filebuf_open(&file, hintpath == NULL ? "streamed" : hintpath, GIT_FILEBUF_TEMPORARY) < 0)
270
+ if (git_filebuf_open(&file, git_buf_cstr(&path), GIT_FILEBUF_TEMPORARY) < 0)
262
271
  goto cleanup;
263
272
 
264
273
  while (1) {
@@ -282,6 +291,7 @@ int git_blob_create_fromchunks(
282
291
  error = blob_create_internal(oid, repo, file.path_lock, hintpath, hintpath != NULL);
283
292
 
284
293
  cleanup:
294
+ git_buf_free(&path);
285
295
  git_filebuf_cleanup(&file);
286
296
  git__free(content);
287
297
  return error;
@@ -50,6 +50,12 @@ static int create_error_invalid(const char *msg)
50
50
  return -1;
51
51
  }
52
52
 
53
+ static int not_a_local_branch(git_reference *ref)
54
+ {
55
+ giterr_set(GITERR_INVALID, "Reference '%s' is not a local branch.", git_reference_name(ref));
56
+ return -1;
57
+ }
58
+
53
59
  int git_branch_create(
54
60
  git_reference **ref_out,
55
61
  git_repository *repository,
@@ -57,7 +63,6 @@ int git_branch_create(
57
63
  const git_object *target,
58
64
  int force)
59
65
  {
60
- git_otype target_type = GIT_OBJ_BAD;
61
66
  git_object *commit = NULL;
62
67
  git_reference *branch = NULL;
63
68
  git_buf canonical_branch_name = GIT_BUF_INIT;
@@ -66,80 +71,46 @@ int git_branch_create(
66
71
  assert(branch_name && target && ref_out);
67
72
  assert(git_object_owner(target) == repository);
68
73
 
69
- target_type = git_object_type(target);
70
-
71
- switch (target_type)
72
- {
73
- case GIT_OBJ_TAG:
74
- if (git_tag_peel(&commit, (git_tag *)target) < 0)
75
- goto cleanup;
76
-
77
- if (git_object_type(commit) != GIT_OBJ_COMMIT) {
78
- create_error_invalid("The given target does not resolve to a commit");
79
- goto cleanup;
80
- }
81
- break;
82
-
83
- case GIT_OBJ_COMMIT:
84
- commit = (git_object *)target;
85
- break;
86
-
87
- default:
88
- return create_error_invalid("Only git_tag and git_commit objects are valid targets.");
89
- }
74
+ if (git_object_peel(&commit, (git_object *)target, GIT_OBJ_COMMIT) < 0)
75
+ return create_error_invalid("The given target does not resolve to a commit");
90
76
 
91
77
  if (git_buf_joinpath(&canonical_branch_name, GIT_REFS_HEADS_DIR, branch_name) < 0)
92
78
  goto cleanup;
93
79
 
94
- if (git_reference_create_oid(&branch, repository,
95
- git_buf_cstr(&canonical_branch_name), git_object_id(commit), force) < 0)
96
- goto cleanup;
80
+ error = git_reference_create_oid(&branch, repository,
81
+ git_buf_cstr(&canonical_branch_name), git_object_id(commit), force);
97
82
 
98
- *ref_out = branch;
99
- error = 0;
83
+ if (!error)
84
+ *ref_out = branch;
100
85
 
101
86
  cleanup:
102
- if (target_type == GIT_OBJ_TAG)
103
- git_object_free(commit);
104
-
87
+ git_object_free(commit);
105
88
  git_buf_free(&canonical_branch_name);
106
89
  return error;
107
90
  }
108
91
 
109
- int git_branch_delete(git_repository *repo, const char *branch_name, git_branch_t branch_type)
92
+ int git_branch_delete(git_reference *branch)
110
93
  {
111
- git_reference *branch = NULL;
112
- git_reference *head = NULL;
113
- int error;
114
-
115
- assert(repo && branch_name);
116
- assert((branch_type == GIT_BRANCH_LOCAL) || (branch_type == GIT_BRANCH_REMOTE));
94
+ int is_head;
117
95
 
118
- if ((error = retrieve_branch_reference(&branch, repo, branch_name, branch_type == GIT_BRANCH_REMOTE)) < 0)
119
- return error;
96
+ assert(branch);
120
97
 
121
- if (git_reference_lookup(&head, repo, GIT_HEAD_FILE) < 0) {
122
- giterr_set(GITERR_REFERENCE, "Cannot locate HEAD.");
123
- goto on_error;
124
- }
125
-
126
- if ((git_reference_type(head) == GIT_REF_SYMBOLIC)
127
- && (strcmp(git_reference_target(head), git_reference_name(branch)) == 0)) {
128
- giterr_set(GITERR_REFERENCE,
129
- "Cannot delete branch '%s' as it is the current HEAD of the repository.", branch_name);
130
- goto on_error;
98
+ if (!git_reference_is_branch(branch) &&
99
+ !git_reference_is_remote(branch)) {
100
+ giterr_set(GITERR_INVALID, "Reference '%s' is not a valid branch.", git_reference_name(branch));
101
+ return -1;
131
102
  }
132
103
 
133
- if (git_reference_delete(branch) < 0)
134
- goto on_error;
104
+ if ((is_head = git_branch_is_head(branch)) < 0)
105
+ return is_head;
135
106
 
136
- git_reference_free(head);
137
- return 0;
107
+ if (is_head) {
108
+ giterr_set(GITERR_REFERENCE,
109
+ "Cannot delete branch '%s' as it is the current HEAD of the repository.", git_reference_name(branch));
110
+ return -1;
111
+ }
138
112
 
139
- on_error:
140
- git_reference_free(head);
141
- git_reference_free(branch);
142
- return -1;
113
+ return git_reference_delete(branch);
143
114
  }
144
115
 
145
116
  typedef struct {
@@ -185,12 +156,6 @@ int git_branch_foreach(
185
156
  return git_reference_foreach(repo, GIT_REF_LISTALL, &branch_foreach_cb, (void *)&filter);
186
157
  }
187
158
 
188
- static int not_a_local_branch(git_reference *ref)
189
- {
190
- giterr_set(GITERR_INVALID, "Reference '%s' is not a local branch.", git_reference_name(ref));
191
- return -1;
192
- }
193
-
194
159
  int git_branch_move(
195
160
  git_reference *branch,
196
161
  const char *new_branch_name,
@@ -271,9 +236,11 @@ int git_branch_tracking(
271
236
  goto cleanup;
272
237
 
273
238
  refspec = git_remote_fetchspec(remote);
274
- if (refspec == NULL) {
275
- error = GIT_ENOTFOUND;
276
- goto cleanup;
239
+ if (refspec == NULL
240
+ || refspec->src == NULL
241
+ || refspec->dst == NULL) {
242
+ error = GIT_ENOTFOUND;
243
+ goto cleanup;
277
244
  }
278
245
 
279
246
  if (git_refspec_transform_r(&buf, refspec, merge_name) < 0)
@@ -292,3 +259,32 @@ cleanup:
292
259
  git_buf_free(&buf);
293
260
  return error;
294
261
  }
262
+
263
+ int git_branch_is_head(
264
+ git_reference *branch)
265
+ {
266
+ git_reference *head;
267
+ bool is_same = false;
268
+ int error;
269
+
270
+ assert(branch);
271
+
272
+ if (!git_reference_is_branch(branch))
273
+ return false;
274
+
275
+ error = git_repository_head(&head, git_reference_owner(branch));
276
+
277
+ if (error == GIT_EORPHANEDHEAD)
278
+ return false;
279
+
280
+ if (error < 0)
281
+ return -1;
282
+
283
+ is_same = strcmp(
284
+ git_reference_name(branch),
285
+ git_reference_name(head)) == 0;
286
+
287
+ git_reference_free(head);
288
+
289
+ return is_same;
290
+ }