rugged 0.24.0b8 → 0.24.0b9

Sign up to get free protection for your applications and to get access to all the features.
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
  }