rugged 0.24.0b8 → 0.24.0b9

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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/ext/rugged/rugged_tree.c +7 -3
  3. data/lib/rugged/version.rb +1 -1
  4. data/vendor/libgit2/CMakeLists.txt +27 -1
  5. data/vendor/libgit2/include/git2/common.h +12 -7
  6. data/vendor/libgit2/include/git2/diff.h +24 -5
  7. data/vendor/libgit2/include/git2/merge.h +31 -13
  8. data/vendor/libgit2/include/git2/repository.h +2 -0
  9. data/vendor/libgit2/include/git2/submodule.h +12 -1
  10. data/vendor/libgit2/include/git2/sys/stream.h +13 -0
  11. data/vendor/libgit2/include/git2/sys/transport.h +1 -0
  12. data/vendor/libgit2/src/annotated_commit.c +71 -18
  13. data/vendor/libgit2/src/annotated_commit.h +26 -1
  14. data/vendor/libgit2/src/checkout.c +1 -2
  15. data/vendor/libgit2/src/commit.c +25 -10
  16. data/vendor/libgit2/src/common.h +1 -0
  17. data/vendor/libgit2/src/config_file.c +5 -10
  18. data/vendor/libgit2/src/diff.c +18 -21
  19. data/vendor/libgit2/src/diff.h +0 -1
  20. data/vendor/libgit2/src/diff_file.c +25 -0
  21. data/vendor/libgit2/src/filebuf.c +6 -0
  22. data/vendor/libgit2/src/fileops.c +54 -29
  23. data/vendor/libgit2/src/fileops.h +3 -2
  24. data/vendor/libgit2/src/global.c +5 -0
  25. data/vendor/libgit2/src/global.h +2 -0
  26. data/vendor/libgit2/src/index.c +105 -58
  27. data/vendor/libgit2/src/index.h +39 -0
  28. data/vendor/libgit2/src/merge.c +303 -104
  29. data/vendor/libgit2/src/merge.h +2 -2
  30. data/vendor/libgit2/src/object.c +0 -2
  31. data/vendor/libgit2/src/pool.c +16 -8
  32. data/vendor/libgit2/src/refdb_fs.c +15 -5
  33. data/vendor/libgit2/src/refs.h +5 -0
  34. data/vendor/libgit2/src/repository.c +10 -3
  35. data/vendor/libgit2/src/reset.c +6 -6
  36. data/vendor/libgit2/src/settings.c +31 -3
  37. data/vendor/libgit2/src/stream.h +3 -0
  38. data/vendor/libgit2/src/submodule.c +19 -25
  39. data/vendor/libgit2/src/tls_stream.c +13 -0
  40. data/vendor/libgit2/src/transports/http.c +12 -1
  41. data/vendor/libgit2/src/transports/winhttp.c +34 -2
  42. data/vendor/libgit2/src/tree.c +75 -21
  43. data/vendor/libgit2/src/tree.h +5 -2
  44. data/vendor/libgit2/src/win32/mingw-compat.h +0 -6
  45. data/vendor/libgit2/src/win32/msvc-compat.h +0 -3
  46. data/vendor/libgit2/src/win32/w32_util.h +14 -8
  47. data/vendor/libgit2/src/win32/win32-compat.h +42 -0
  48. metadata +3 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a84e4447d122b19232a1d4a1134a15898d088730
4
- data.tar.gz: 027946b6e6c8513aa9436ee9e24b886c924437ba
3
+ metadata.gz: 5974c78d60b9c20faf50ac2b55194b33642a0645
4
+ data.tar.gz: 1bd653d666e62f551e46cdad7973c9bf7942dd3f
5
5
  SHA512:
6
- metadata.gz: 95611e993578c036601909af7215eebe76eeb42a4c2a919ac1a59c2a580cf5743198843eb946b3e210d3bacb7faf2403ab3acd6d349cbab8f6cc56b5131b2d2e
7
- data.tar.gz: 4b70d32119d8544c4910dd6b735aa2ce704ba01da9effcbbfbc9ea6f34a97123292d8598394acf05c9f73d2b8066a4a2924c9c6c190127c021fef3007b6d4f57
6
+ metadata.gz: c14940177eeeafd9371ed0eefe67369d06fe7fa50b39359aa375d08210d4b8ffe7a7c3e646b8f363f940ecd1dd6d969324338e45a190f38ff5a3653d8b8d7406
7
+ data.tar.gz: 61a47e6c4e1fd99338244e814fef4c84cc6eda651d2e8ae96698738fd2961c7f20597f0d20e66bed74cddc23d5c5714a5b89a246cd9793ac36d5baa98a29cf74
@@ -614,15 +614,19 @@ void rugged_parse_merge_options(git_merge_options *opts, VALUE rb_options)
614
614
  }
615
615
 
616
616
  if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("renames")))) {
617
- opts->tree_flags |= GIT_MERGE_TREE_FIND_RENAMES;
617
+ opts->flags |= GIT_MERGE_FIND_RENAMES;
618
618
  }
619
619
 
620
620
  if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("fail_on_conflict")))) {
621
- opts->tree_flags |= GIT_MERGE_TREE_FAIL_ON_CONFLICT;
621
+ opts->flags |= GIT_MERGE_FAIL_ON_CONFLICT;
622
622
  }
623
623
 
624
624
  if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("skip_reuc")))) {
625
- opts->tree_flags |= GIT_MERGE_TREE_SKIP_REUC;
625
+ opts->flags |= GIT_MERGE_SKIP_REUC;
626
+ }
627
+
628
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("no_recursive")))) {
629
+ opts->flags |= GIT_MERGE_NO_RECURSIVE;
626
630
  }
627
631
  }
628
632
  }
@@ -1,3 +1,3 @@
1
1
  module Rugged
2
- Version = VERSION = '0.24.0b8'
2
+ Version = VERSION = '0.24.0b9'
3
3
  end
@@ -20,6 +20,7 @@ SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Mo
20
20
 
21
21
  INCLUDE(CheckLibraryExists)
22
22
  INCLUDE(CheckFunctionExists)
23
+ INCLUDE(CheckStructHasMember)
23
24
  INCLUDE(AddCFlagIfSupported)
24
25
  INCLUDE(FindPkgConfig)
25
26
 
@@ -85,6 +86,23 @@ IF (NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
85
86
  OPTION( USE_OPENSSL "Link with and use openssl library" ON )
86
87
  ENDIF()
87
88
 
89
+ CHECK_STRUCT_HAS_MEMBER ("struct stat" st_atim "sys/types.h;sys/stat.h"
90
+ HAVE_STRUCT_STAT_ST_ATIM LANGUAGE C)
91
+ CHECK_STRUCT_HAS_MEMBER ("struct stat" st_atimespec "sys/types.h;sys/stat.h"
92
+ HAVE_STRUCT_STAT_ST_ATIMESPEC LANGUAGE C)
93
+
94
+ IF (HAVE_STRUCT_STAT_ST_ATIM)
95
+ CHECK_STRUCT_HAS_MEMBER("struct stat" st_mtim.tv_nsec sys/stat.h
96
+ HAVE_STRUCT_STAT_NSEC LANGUAGE C)
97
+ ELSEIF (HAVE_STRUCT_STAT_ST_ATIMESPEC)
98
+ CHECK_STRUCT_HAS_MEMBER("struct stat" st_mtimespec.tv_nsec sys/stat.h
99
+ HAVE_STRUCT_STAT_NSEC LANGUAGE C)
100
+ ENDIF()
101
+
102
+ IF (HAVE_STRUCT_STAT_NSEC OR WIN32)
103
+ OPTION( USE_NSEC "Care about sub-second file mtimes and ctimes" OFF )
104
+ ENDIF()
105
+
88
106
  # This variable will contain the libraries we need to put into
89
107
  # libgit2.pc's Requires.private. That is, what we're linking to or
90
108
  # what someone who's statically linking us needs to link to.
@@ -217,7 +235,7 @@ IF (WIN32 AND WINHTTP)
217
235
  SET(LIBWINHTTP_PATH "${CMAKE_CURRENT_BINARY_DIR}/deps/winhttp")
218
236
  FILE(MAKE_DIRECTORY ${LIBWINHTTP_PATH})
219
237
 
220
- IF ("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
238
+ IF (CMAKE_SIZEOF_VOID_P EQUAL 8)
221
239
  set(WINHTTP_DEF "${CMAKE_CURRENT_SOURCE_DIR}/deps/winhttp/winhttp64.def")
222
240
  ELSE()
223
241
  set(WINHTTP_DEF "${CMAKE_CURRENT_SOURCE_DIR}/deps/winhttp/winhttp.def")
@@ -516,6 +534,14 @@ IF (THREADSAFE)
516
534
  ADD_DEFINITIONS(-DGIT_THREADS)
517
535
  ENDIF()
518
536
 
537
+ IF (USE_NSEC)
538
+ ADD_DEFINITIONS(-DGIT_USE_NSEC)
539
+ ENDIF()
540
+
541
+ IF (HAVE_STRUCT_STAT_ST_ATIMESPEC)
542
+ ADD_DEFINITIONS(-DGIT_USE_STAT_ATIMESPEC)
543
+ ENDIF()
544
+
519
545
  ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64)
520
546
 
521
547
  # Collect sourcefiles
@@ -101,8 +101,9 @@ GIT_EXTERN(void) git_libgit2_version(int *major, int *minor, int *rev);
101
101
  */
102
102
  typedef enum {
103
103
  GIT_FEATURE_THREADS = (1 << 0),
104
- GIT_FEATURE_HTTPS = (1 << 1),
105
- GIT_FEATURE_SSH = (1 << 2),
104
+ GIT_FEATURE_HTTPS = (1 << 1),
105
+ GIT_FEATURE_SSH = (1 << 2),
106
+ GIT_FEATURE_NSEC = (1 << 3),
106
107
  } git_feature_t;
107
108
 
108
109
  /**
@@ -145,6 +146,7 @@ typedef enum {
145
146
  GIT_OPT_GET_TEMPLATE_PATH,
146
147
  GIT_OPT_SET_TEMPLATE_PATH,
147
148
  GIT_OPT_SET_SSL_CERT_LOCATIONS,
149
+ GIT_OPT_SET_USER_AGENT,
148
150
  } git_libgit2_opt_t;
149
151
 
150
152
  /**
@@ -172,9 +174,9 @@ typedef enum {
172
174
  * * opts(GIT_OPT_GET_SEARCH_PATH, int level, git_buf *buf)
173
175
  *
174
176
  * > Get the search path for a given level of config data. "level" must
175
- * > be one of `GIT_CONFIG_LEVEL_SYSTEM`, `GIT_CONFIG_LEVEL_GLOBAL`, or
176
- * > `GIT_CONFIG_LEVEL_XDG`. The search path is written to the `out`
177
- * > buffer.
177
+ * > be one of `GIT_CONFIG_LEVEL_SYSTEM`, `GIT_CONFIG_LEVEL_GLOBAL`,
178
+ * > `GIT_CONFIG_LEVEL_XDG`, or `GIT_CONFIG_LEVEL_PROGRAMDATA`.
179
+ * > The search path is written to the `out` buffer.
178
180
  *
179
181
  * * opts(GIT_OPT_SET_SEARCH_PATH, int level, const char *path)
180
182
  *
@@ -186,8 +188,9 @@ typedef enum {
186
188
  * > variables). Use magic path `$PATH` to include the old value
187
189
  * > of the path (if you want to prepend or append, for instance).
188
190
  * >
189
- * > - `level` must be GIT_CONFIG_LEVEL_SYSTEM, GIT_CONFIG_LEVEL_GLOBAL,
190
- * > or GIT_CONFIG_LEVEL_XDG.
191
+ * > - `level` must be `GIT_CONFIG_LEVEL_SYSTEM`,
192
+ * > `GIT_CONFIG_LEVEL_GLOBAL`, `GIT_CONFIG_LEVEL_XDG`, or
193
+ * > `GIT_CONFIG_LEVEL_PROGRAMDATA`.
191
194
  *
192
195
  * * opts(GIT_OPT_SET_CACHE_OBJECT_LIMIT, git_otype type, size_t size)
193
196
  *
@@ -240,6 +243,8 @@ typedef enum {
240
243
  * >
241
244
  * > Either parameter may be `NULL`, but not both.
242
245
  *
246
+ * * opts(GIT_OPT_SET_USER_AGENT, const char *user_agent)
247
+ *
243
248
  * @param option Option key
244
249
  * @param ... value to set the option
245
250
  * @return 0 on success, <0 on failure
@@ -350,6 +350,22 @@ typedef int (*git_diff_notify_cb)(
350
350
  const char *matched_pathspec,
351
351
  void *payload);
352
352
 
353
+ /**
354
+ * Diff progress callback.
355
+ *
356
+ * Called before each file comparison.
357
+ *
358
+ * @param diff_so_far The diff being generated.
359
+ * @param old_path The path to the old file or NULL.
360
+ * @param new_path The path to the new file or NULL.
361
+ * @return Non-zero to abort the diff.
362
+ */
363
+ typedef int (*git_diff_progress_cb)(
364
+ const git_diff *diff_so_far,
365
+ const char *old_path,
366
+ const char *new_path,
367
+ void *payload);
368
+
353
369
  /**
354
370
  * Structure describing options about how the diff should be executed.
355
371
  *
@@ -370,8 +386,10 @@ typedef int (*git_diff_notify_cb)(
370
386
  * - `max_size` is a file size (in bytes) above which a blob will be marked
371
387
  * as binary automatically; pass a negative value to disable.
372
388
  * - `notify_cb` is an optional callback function, notifying the consumer of
373
- * which files are being examined as the diff is generated
374
- * - `notify_payload` is the payload data to pass to the `notify_cb` function
389
+ * changes to the diff as new deltas are added.
390
+ * - `progress_cb` is an optional callback function, notifying the consumer of
391
+ * which files are being examined as the diff is generated.
392
+ * - `payload` is the payload to pass to the callback functions.
375
393
  * - `ignore_submodules` overrides the submodule ignore setting for all
376
394
  * submodules in the diff.
377
395
  */
@@ -383,8 +401,9 @@ typedef struct {
383
401
 
384
402
  git_submodule_ignore_t ignore_submodules; /**< submodule ignore rule */
385
403
  git_strarray pathspec; /**< defaults to include all paths */
386
- git_diff_notify_cb notify_cb;
387
- void *notify_payload;
404
+ git_diff_notify_cb notify_cb;
405
+ git_diff_progress_cb progress_cb;
406
+ void *payload;
388
407
 
389
408
  /* options controlling how to diff text is generated */
390
409
 
@@ -403,7 +422,7 @@ typedef struct {
403
422
  * `git_diff_options_init` programmatic initialization.
404
423
  */
405
424
  #define GIT_DIFF_OPTIONS_INIT \
406
- {GIT_DIFF_OPTIONS_VERSION, 0, GIT_SUBMODULE_IGNORE_UNSPECIFIED, {NULL,0}, NULL, NULL, 3}
425
+ {GIT_DIFF_OPTIONS_VERSION, 0, GIT_SUBMODULE_IGNORE_UNSPECIFIED, {NULL,0}, NULL, NULL, NULL, 3}
407
426
 
408
427
  /**
409
428
  * Initializes a `git_diff_options` with default values. Equivalent to
@@ -62,8 +62,8 @@ GIT_EXTERN(int) git_merge_file_init_input(
62
62
  unsigned int version);
63
63
 
64
64
  /**
65
- * Flags for `git_merge_tree` options. A combination of these flags can be
66
- * passed in via the `tree_flags` value in the `git_merge_options`.
65
+ * Flags for `git_merge` options. A combination of these flags can be
66
+ * passed in via the `flags` value in the `git_merge_options`.
67
67
  */
68
68
  typedef enum {
69
69
  /**
@@ -71,20 +71,28 @@ typedef enum {
71
71
  * side or the common ancestor and the "theirs" side. This will enable
72
72
  * the ability to merge between a modified and renamed file.
73
73
  */
74
- GIT_MERGE_TREE_FIND_RENAMES = (1 << 0),
74
+ GIT_MERGE_FIND_RENAMES = (1 << 0),
75
75
 
76
76
  /**
77
77
  * If a conflict occurs, exit immediately instead of attempting to
78
78
  * continue resolving conflicts. The merge operation will fail with
79
79
  * GIT_EMERGECONFLICT and no index will be returned.
80
80
  */
81
- GIT_MERGE_TREE_FAIL_ON_CONFLICT = (1 << 1),
81
+ GIT_MERGE_FAIL_ON_CONFLICT = (1 << 1),
82
82
 
83
83
  /**
84
84
  * Do not write the REUC extension on the generated index
85
85
  */
86
- GIT_MERGE_TREE_SKIP_REUC = (1 << 2),
87
- } git_merge_tree_flag_t;
86
+ GIT_MERGE_SKIP_REUC = (1 << 2),
87
+
88
+ /**
89
+ * If the commits being merged have multiple merge bases, do not build
90
+ * a recursive merge base (by merging the multiple merge bases),
91
+ * instead simply use the first base. This flag provides a similar
92
+ * merge base to `git-merge-resolve`.
93
+ */
94
+ GIT_MERGE_NO_RECURSIVE = (1 << 3),
95
+ } git_merge_flag_t;
88
96
 
89
97
  /**
90
98
  * Merge file favor options for `git_merge_options` instruct the file-level
@@ -152,7 +160,7 @@ typedef enum {
152
160
 
153
161
  /** Take extra time to find minimal diff */
154
162
  GIT_MERGE_FILE_DIFF_MINIMAL = (1 << 7),
155
- } git_merge_file_flags_t;
163
+ } git_merge_file_flag_t;
156
164
 
157
165
  /**
158
166
  * Options for merging a file
@@ -181,8 +189,8 @@ typedef struct {
181
189
  /** The file to favor in region conflicts. */
182
190
  git_merge_file_favor_t favor;
183
191
 
184
- /** see `git_merge_file_flags_t` above */
185
- unsigned int flags;
192
+ /** see `git_merge_file_flag_t` above */
193
+ git_merge_file_flag_t flags;
186
194
  } git_merge_file_options;
187
195
 
188
196
  #define GIT_MERGE_FILE_OPTIONS_VERSION 1
@@ -232,11 +240,13 @@ typedef struct {
232
240
  */
233
241
  typedef struct {
234
242
  unsigned int version;
235
- git_merge_tree_flag_t tree_flags;
243
+
244
+ /** See `git_merge_flag_t` above */
245
+ git_merge_flag_t flags;
236
246
 
237
247
  /**
238
248
  * Similarity to consider a file renamed (default 50). If
239
- * `GIT_MERGE_TREE_FIND_RENAMES` is enabled, added files will be compared
249
+ * `GIT_MERGE_FIND_RENAMES` is enabled, added files will be compared
240
250
  * with deleted files to determine their similarity. Files that are
241
251
  * more similar than the rename threshold (percentage-wise) will be
242
252
  * treated as a rename.
@@ -255,11 +265,19 @@ typedef struct {
255
265
  /** Pluggable similarity metric; pass NULL to use internal metric */
256
266
  git_diff_similarity_metric *metric;
257
267
 
268
+ /**
269
+ * Maximum number of times to merge common ancestors to build a
270
+ * virtual merge base when faced with criss-cross merges. When this
271
+ * limit is reached, the next ancestor will simply be used instead of
272
+ * attempting to merge it. The default is unlimited.
273
+ */
274
+ unsigned int recursion_limit;
275
+
258
276
  /** Flags for handling conflicting content. */
259
277
  git_merge_file_favor_t file_favor;
260
278
 
261
- /** see `git_merge_file_flags_t` above */
262
- unsigned int file_flags;
279
+ /** see `git_merge_file_flag_t` above */
280
+ git_merge_file_flag_t file_flags;
263
281
  } git_merge_options;
264
282
 
265
283
  #define GIT_MERGE_OPTIONS_VERSION 1
@@ -675,7 +675,9 @@ typedef enum {
675
675
  GIT_REPOSITORY_STATE_NONE,
676
676
  GIT_REPOSITORY_STATE_MERGE,
677
677
  GIT_REPOSITORY_STATE_REVERT,
678
+ GIT_REPOSITORY_STATE_REVERT_SEQUENCE,
678
679
  GIT_REPOSITORY_STATE_CHERRYPICK,
680
+ GIT_REPOSITORY_STATE_CHERRYPICK_SEQUENCE,
679
681
  GIT_REPOSITORY_STATE_BISECT,
680
682
  GIT_REPOSITORY_STATE_REBASE,
681
683
  GIT_REPOSITORY_STATE_REBASE_INTERACTIVE,
@@ -107,6 +107,17 @@ typedef enum {
107
107
  GIT_SUBMODULE_STATUS_WD_WD_MODIFIED | \
108
108
  GIT_SUBMODULE_STATUS_WD_UNTRACKED)) != 0)
109
109
 
110
+ /**
111
+ * Function pointer to receive each submodule
112
+ *
113
+ * @param sm git_submodule currently being visited
114
+ * @param name name of the submodule
115
+ * @param payload value you passed to the foreach function as payload
116
+ * @return 0 on success or error code
117
+ */
118
+ typedef int (*git_submodule_cb)(
119
+ git_submodule *sm, const char *name, void *payload);
120
+
110
121
  /**
111
122
  * Submodule update options structure
112
123
  *
@@ -239,7 +250,7 @@ GIT_EXTERN(void) git_submodule_free(git_submodule *submodule);
239
250
  */
240
251
  GIT_EXTERN(int) git_submodule_foreach(
241
252
  git_repository *repo,
242
- int (*callback)(git_submodule *sm, const char *name, void *payload),
253
+ git_submodule_cb callback,
243
254
  void *payload);
244
255
 
245
256
  /**
@@ -39,6 +39,19 @@ typedef struct git_stream {
39
39
  void (*free)(struct git_stream *);
40
40
  } git_stream;
41
41
 
42
+ typedef int (*git_stream_cb)(git_stream **out, const char *host, const char *port);
43
+
44
+ /**
45
+ * Register a TLS stream constructor for the library to use
46
+ *
47
+ * If a constructor is already set, it will be overwritten. Pass
48
+ * `NULL` in order to deregister the current constructor.
49
+ *
50
+ * @param ctor the constructor to use
51
+ * @return 0 or an error code
52
+ */
53
+ GIT_EXTERN(int) git_stream_register_tls(git_stream_cb ctor);
54
+
42
55
  GIT_END_DECL
43
56
 
44
57
  #endif
@@ -10,6 +10,7 @@
10
10
 
11
11
  #include "git2/net.h"
12
12
  #include "git2/types.h"
13
+ #include "git2/strarray.h"
13
14
 
14
15
  /**
15
16
  * @file git2/sys/transport.h
@@ -7,12 +7,16 @@
7
7
 
8
8
  #include "common.h"
9
9
  #include "annotated_commit.h"
10
+ #include "refs.h"
11
+ #include "cache.h"
10
12
 
11
13
  #include "git2/commit.h"
12
14
  #include "git2/refs.h"
13
15
  #include "git2/repository.h"
14
16
  #include "git2/annotated_commit.h"
15
17
  #include "git2/revparse.h"
18
+ #include "git2/tree.h"
19
+ #include "git2/index.h"
16
20
 
17
21
  static int annotated_commit_init(
18
22
  git_annotated_commit **out,
@@ -22,14 +26,17 @@ static int annotated_commit_init(
22
26
  const char *remote_url)
23
27
  {
24
28
  git_annotated_commit *annotated_commit;
29
+ git_commit *commit = NULL;
25
30
  int error = 0;
26
31
 
27
32
  assert(out && id);
28
33
 
29
34
  *out = NULL;
30
35
 
31
- annotated_commit = git__calloc(1, sizeof(git_annotated_commit));
32
- GITERR_CHECK_ALLOC(annotated_commit);
36
+ if ((error = git_commit_lookup(&commit, repo, id)) < 0 ||
37
+ (error = git_annotated_commit_from_commit(&annotated_commit,
38
+ commit)) < 0)
39
+ goto done;
33
40
 
34
41
  if (ref_name) {
35
42
  annotated_commit->ref_name = git__strdup(ref_name);
@@ -41,15 +48,10 @@ static int annotated_commit_init(
41
48
  GITERR_CHECK_ALLOC(annotated_commit->remote_url);
42
49
  }
43
50
 
44
- git_oid_fmt(annotated_commit->id_str, id);
45
- annotated_commit->id_str[GIT_OID_HEXSZ] = '\0';
46
-
47
- if ((error = git_commit_lookup(&annotated_commit->commit, repo, id)) < 0) {
48
- git_annotated_commit_free(annotated_commit);
49
- return error;
50
- }
51
-
52
51
  *out = annotated_commit;
52
+
53
+ done:
54
+ git_commit_free(commit);
53
55
  return error;
54
56
  }
55
57
 
@@ -75,6 +77,51 @@ int git_annotated_commit_from_ref(
75
77
  return error;
76
78
  }
77
79
 
80
+ int git_annotated_commit_from_head(
81
+ git_annotated_commit **out,
82
+ git_repository *repo)
83
+ {
84
+ git_reference *head;
85
+ int error;
86
+
87
+ assert(out && repo);
88
+
89
+ *out = NULL;
90
+
91
+ if ((error = git_reference_lookup(&head, repo, GIT_HEAD_FILE)) < 0)
92
+ return -1;
93
+
94
+ error = git_annotated_commit_from_ref(out, repo, head);
95
+
96
+ git_reference_free(head);
97
+ return error;
98
+ }
99
+
100
+ int git_annotated_commit_from_commit(
101
+ git_annotated_commit **out,
102
+ git_commit *commit)
103
+ {
104
+ git_annotated_commit *annotated_commit;
105
+
106
+ assert(out && commit);
107
+
108
+ *out = NULL;
109
+
110
+ annotated_commit = git__calloc(1, sizeof(git_annotated_commit));
111
+ GITERR_CHECK_ALLOC(annotated_commit);
112
+
113
+ annotated_commit->type = GIT_ANNOTATED_COMMIT_REAL;
114
+
115
+ git_cached_obj_incref(commit);
116
+ annotated_commit->commit = commit;
117
+
118
+ git_oid_fmt(annotated_commit->id_str, git_commit_id(commit));
119
+ annotated_commit->id_str[GIT_OID_HEXSZ] = '\0';
120
+
121
+ *out = annotated_commit;
122
+ return 0;
123
+ }
124
+
78
125
  int git_annotated_commit_lookup(
79
126
  git_annotated_commit **out,
80
127
  git_repository *repo,
@@ -136,14 +183,20 @@ void git_annotated_commit_free(git_annotated_commit *annotated_commit)
136
183
  if (annotated_commit == NULL)
137
184
  return;
138
185
 
139
- if (annotated_commit->commit != NULL)
140
- git_commit_free(annotated_commit->commit);
141
-
142
- if (annotated_commit->ref_name != NULL)
143
- git__free(annotated_commit->ref_name);
144
-
145
- if (annotated_commit->remote_url != NULL)
146
- git__free(annotated_commit->remote_url);
186
+ switch (annotated_commit->type) {
187
+ case GIT_ANNOTATED_COMMIT_REAL:
188
+ git_commit_free(annotated_commit->commit);
189
+ git_tree_free(annotated_commit->tree);
190
+ git__free(annotated_commit->ref_name);
191
+ git__free(annotated_commit->remote_url);
192
+ break;
193
+ case GIT_ANNOTATED_COMMIT_VIRTUAL:
194
+ git_index_free(annotated_commit->index);
195
+ git_array_clear(annotated_commit->parents);
196
+ break;
197
+ default:
198
+ abort();
199
+ }
147
200
 
148
201
  git__free(annotated_commit);
149
202
  }