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
@@ -13,6 +13,7 @@
13
13
  #include "path.h"
14
14
  #include "pool.h"
15
15
  #include "strmap.h"
16
+ #include "oid.h"
16
17
 
17
18
  /**
18
19
  * Filebuffer methods
@@ -21,7 +22,7 @@
21
22
  */
22
23
  extern int git_futils_readbuffer(git_buf *obj, const char *path);
23
24
  extern int git_futils_readbuffer_updated(
24
- git_buf *obj, const char *path, time_t *mtime, size_t *size, int *updated);
25
+ git_buf *obj, const char *path, git_oid *checksum, int *updated);
25
26
  extern int git_futils_readbuffer_fd(git_buf *obj, git_file fd, size_t len);
26
27
 
27
28
  extern int git_futils_writebuffer(
@@ -309,7 +310,7 @@ extern int git_futils_fake_symlink(const char *new, const char *old);
309
310
  * versions could be implemented in the future.
310
311
  */
311
312
  typedef struct {
312
- git_time_t mtime;
313
+ struct timespec mtime;
313
314
  git_off_t size;
314
315
  unsigned int ino;
315
316
  } git_futils_filestamp;
@@ -31,6 +31,7 @@ static git_mutex *openssl_locks;
31
31
  static git_global_shutdown_fn git__shutdown_callbacks[MAX_SHUTDOWN_CB];
32
32
  static git_atomic git__n_shutdown_callbacks;
33
33
  static git_atomic git__n_inits;
34
+ char *git__user_agent;
34
35
 
35
36
  void git__on_shutdown(git_global_shutdown_fn callback)
36
37
  {
@@ -269,6 +270,8 @@ int git_libgit2_shutdown(void)
269
270
  git_win32__crtdbg_stacktrace_cleanup();
270
271
  git_win32__stack_cleanup();
271
272
  #endif
273
+
274
+ git__free(git__user_agent);
272
275
  }
273
276
 
274
277
  /* Exit the lock */
@@ -369,6 +372,7 @@ int git_libgit2_shutdown(void)
369
372
 
370
373
  git__global_state_cleanup(ptr);
371
374
  git__free(ptr);
375
+ git__free(git__user_agent);
372
376
 
373
377
  pthread_key_delete(_tls_key);
374
378
  git_mutex_free(&git__mwindow_mutex);
@@ -423,6 +427,7 @@ int git_libgit2_shutdown(void)
423
427
  git__shutdown();
424
428
  git__global_state_cleanup(&__state);
425
429
  uninit_ssl();
430
+ git__free(git__user_agent);
426
431
 
427
432
  return 0;
428
433
  }
@@ -35,4 +35,6 @@ extern void git__on_shutdown(git_global_shutdown_fn callback);
35
35
 
36
36
  extern void git__free_tls_data(void);
37
37
 
38
+ extern const char *git_libgit2__user_agent(void);
39
+
38
40
  #endif
@@ -18,6 +18,7 @@
18
18
  #include "ignore.h"
19
19
  #include "blob.h"
20
20
  #include "idxmap.h"
21
+ #include "diff.h"
21
22
 
22
23
  #include "git2/odb.h"
23
24
  #include "git2/oid.h"
@@ -719,18 +720,13 @@ int git_index__changed_relative_to(
719
720
  return !!git_oid_cmp(&index->checksum, checksum);
720
721
  }
721
722
 
722
- static bool is_racy_timestamp(git_time_t stamp, git_index_entry *entry)
723
+ static bool is_racy_entry(git_index *index, const git_index_entry *entry)
723
724
  {
724
725
  /* Git special-cases submodules in the check */
725
726
  if (S_ISGITLINK(entry->mode))
726
727
  return false;
727
728
 
728
- /* If we never read the index, we can't have this race either */
729
- if (stamp == 0)
730
- return false;
731
-
732
- /* If the timestamp is the same or newer than the index, it's racy */
733
- return ((int32_t) stamp) <= entry->mtime.seconds;
729
+ return git_index_entry_newer_than_index(entry, index);
734
730
  }
735
731
 
736
732
  /*
@@ -742,9 +738,10 @@ static int truncate_racily_clean(git_index *index)
742
738
  size_t i;
743
739
  int error;
744
740
  git_index_entry *entry;
745
- git_time_t ts = index->stamp.mtime;
746
741
  git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
747
- git_diff *diff;
742
+ git_diff *diff = NULL;
743
+ git_vector paths = GIT_VECTOR_INIT;
744
+ git_diff_delta *delta;
748
745
 
749
746
  /* Nothing to do if there's no repo to talk about */
750
747
  if (!INDEX_OWNER(index))
@@ -756,22 +753,33 @@ static int truncate_racily_clean(git_index *index)
756
753
 
757
754
  diff_opts.flags |= GIT_DIFF_INCLUDE_TYPECHANGE | GIT_DIFF_IGNORE_SUBMODULES | GIT_DIFF_DISABLE_PATHSPEC_MATCH;
758
755
  git_vector_foreach(&index->entries, i, entry) {
759
- if (!is_racy_timestamp(ts, entry))
760
- continue;
756
+ if ((entry->flags_extended & GIT_IDXENTRY_UPTODATE) == 0 &&
757
+ is_racy_entry(index, entry))
758
+ git_vector_insert(&paths, (char *)entry->path);
759
+ }
761
760
 
762
- /* TODO: use the (non-fnmatching) filelist iterator */
763
- diff_opts.pathspec.count = 1;
764
- diff_opts.pathspec.strings = (char **) &entry->path;
761
+ if (paths.length == 0)
762
+ goto done;
765
763
 
766
- if ((error = git_diff_index_to_workdir(&diff, INDEX_OWNER(index), index, &diff_opts)) < 0)
767
- return error;
764
+ diff_opts.pathspec.count = paths.length;
765
+ diff_opts.pathspec.strings = (char **)paths.contents;
768
766
 
769
- if (git_diff_num_deltas(diff) > 0)
770
- entry->file_size = 0;
767
+ if ((error = git_diff_index_to_workdir(&diff, INDEX_OWNER(index), index, &diff_opts)) < 0)
768
+ return error;
771
769
 
772
- git_diff_free(diff);
770
+ git_vector_foreach(&diff->deltas, i, delta) {
771
+ entry = (git_index_entry *)git_index_get_bypath(index, delta->old_file.path, 0);
772
+
773
+ /* Ensure that we have a stage 0 for this file (ie, it's not a
774
+ * conflict), otherwise smudging it is quite pointless.
775
+ */
776
+ if (entry)
777
+ entry->file_size = 0;
773
778
  }
774
779
 
780
+ done:
781
+ git_diff_free(diff);
782
+ git_vector_free(&paths);
775
783
  return 0;
776
784
  }
777
785
 
@@ -858,8 +866,10 @@ void git_index_entry__init_from_stat(
858
866
  {
859
867
  entry->ctime.seconds = (git_time_t)st->st_ctime;
860
868
  entry->mtime.seconds = (git_time_t)st->st_mtime;
861
- /* entry->mtime.nanoseconds = st->st_mtimensec; */
862
- /* entry->ctime.nanoseconds = st->st_ctimensec; */
869
+ #if defined(GIT_USE_NSEC)
870
+ entry->mtime.nanoseconds = st->st_mtim.tv_nsec;
871
+ entry->ctime.nanoseconds = st->st_ctim.tv_nsec;
872
+ #endif
863
873
  entry->dev = st->st_rdev;
864
874
  entry->ino = st->st_ino;
865
875
  entry->mode = (!trust_mode && S_ISREG(st->st_mode)) ?
@@ -979,20 +989,11 @@ static int index_entry_reuc_init(git_index_reuc_entry **reuc_out,
979
989
 
980
990
  static void index_entry_cpy(
981
991
  git_index_entry *tgt,
982
- git_index *index,
983
- const git_index_entry *src,
984
- bool update_path)
992
+ const git_index_entry *src)
985
993
  {
986
994
  const char *tgt_path = tgt->path;
987
995
  memcpy(tgt, src, sizeof(*tgt));
988
-
989
- /* keep the existing path buffer, but update the path to the one
990
- * given by the caller, if we trust it.
991
- */
992
996
  tgt->path = tgt_path;
993
-
994
- if (index->ignore_case && update_path)
995
- memcpy((char *)tgt->path, src->path, strlen(tgt->path));
996
997
  }
997
998
 
998
999
  static int index_entry_dup(
@@ -1000,18 +1001,32 @@ static int index_entry_dup(
1000
1001
  git_index *index,
1001
1002
  const git_index_entry *src)
1002
1003
  {
1003
- git_index_entry *entry;
1004
+ if (index_entry_create(out, INDEX_OWNER(index), src->path) < 0)
1005
+ return -1;
1004
1006
 
1005
- if (!src) {
1006
- *out = NULL;
1007
- return 0;
1008
- }
1007
+ index_entry_cpy(*out, src);
1008
+ return 0;
1009
+ }
1009
1010
 
1010
- if (index_entry_create(&entry, INDEX_OWNER(index), src->path) < 0)
1011
+ static void index_entry_cpy_nocache(
1012
+ git_index_entry *tgt,
1013
+ const git_index_entry *src)
1014
+ {
1015
+ git_oid_cpy(&tgt->id, &src->id);
1016
+ tgt->mode = src->mode;
1017
+ tgt->flags = src->flags;
1018
+ tgt->flags_extended = (src->flags_extended & GIT_IDXENTRY_EXTENDED_FLAGS);
1019
+ }
1020
+
1021
+ static int index_entry_dup_nocache(
1022
+ git_index_entry **out,
1023
+ git_index *index,
1024
+ const git_index_entry *src)
1025
+ {
1026
+ if (index_entry_create(out, INDEX_OWNER(index), src->path) < 0)
1011
1027
  return -1;
1012
1028
 
1013
- index_entry_cpy(entry, index, src, false);
1014
- *out = entry;
1029
+ index_entry_cpy_nocache(*out, src);
1015
1030
  return 0;
1016
1031
  }
1017
1032
 
@@ -1152,7 +1167,7 @@ static int canonicalize_directory_path(
1152
1167
  while ((match = git_vector_get(&index->entries, pos))) {
1153
1168
  if (GIT_IDXENTRY_STAGE(match) != 0) {
1154
1169
  /* conflicts do not contribute to canonical paths */
1155
- } else if (memcmp(search, match->path, search_len) == 0) {
1170
+ } else if (strncmp(search, match->path, search_len) == 0) {
1156
1171
  /* prefer an exact match to the input filename */
1157
1172
  best = match;
1158
1173
  best_len = search_len;
@@ -1272,6 +1287,9 @@ static int index_insert(
1272
1287
  else
1273
1288
  entry->flags |= GIT_IDXENTRY_NAMEMASK;
1274
1289
 
1290
+ /* this entry is now up-to-date and should not be checked for raciness */
1291
+ entry->flags_extended |= GIT_IDXENTRY_UPTODATE;
1292
+
1275
1293
  if (git_mutex_lock(&index->lock) < 0) {
1276
1294
  giterr_set(GITERR_OS, "Unable to acquire index lock");
1277
1295
  return -1;
@@ -1304,8 +1322,13 @@ static int index_insert(
1304
1322
  * and return it in place of the passed in one.
1305
1323
  */
1306
1324
  else if (existing) {
1307
- if (replace)
1308
- index_entry_cpy(existing, index, entry, trust_path);
1325
+ if (replace) {
1326
+ index_entry_cpy(existing, entry);
1327
+
1328
+ if (trust_path)
1329
+ memcpy((char *)existing->path, entry->path, strlen(entry->path));
1330
+ }
1331
+
1309
1332
  index_entry_free(entry);
1310
1333
  *entry_ptr = entry = existing;
1311
1334
  }
@@ -1682,16 +1705,19 @@ int git_index_conflict_add(git_index *index,
1682
1705
 
1683
1706
  assert (index);
1684
1707
 
1685
- if ((ret = index_entry_dup(&entries[0], index, ancestor_entry)) < 0 ||
1686
- (ret = index_entry_dup(&entries[1], index, our_entry)) < 0 ||
1687
- (ret = index_entry_dup(&entries[2], index, their_entry)) < 0)
1708
+ if ((ancestor_entry &&
1709
+ (ret = index_entry_dup(&entries[0], index, ancestor_entry)) < 0) ||
1710
+ (our_entry &&
1711
+ (ret = index_entry_dup(&entries[1], index, our_entry)) < 0) ||
1712
+ (their_entry &&
1713
+ (ret = index_entry_dup(&entries[2], index, their_entry)) < 0))
1688
1714
  goto on_error;
1689
1715
 
1690
1716
  /* Validate entries */
1691
1717
  for (i = 0; i < 3; i++) {
1692
1718
  if (entries[i] && !valid_filemode(entries[i]->mode)) {
1693
1719
  giterr_set(GITERR_INDEX, "invalid filemode for stage %d entry",
1694
- i);
1720
+ i + 1);
1695
1721
  return -1;
1696
1722
  }
1697
1723
  }
@@ -1718,7 +1744,7 @@ int git_index_conflict_add(git_index *index,
1718
1744
  /* Make sure stage is correct */
1719
1745
  GIT_IDXENTRY_STAGE_SET(entries[i], i + 1);
1720
1746
 
1721
- if ((ret = index_insert(index, &entries[i], 0, true, true)) < 0)
1747
+ if ((ret = index_insert(index, &entries[i], 1, true, true)) < 0)
1722
1748
  goto on_error;
1723
1749
 
1724
1750
  entries[i] = NULL; /* don't free if later entry fails */
@@ -2535,7 +2561,8 @@ static int write_disk_entry(git_filebuf *file, git_index_entry *entry)
2535
2561
  if (entry->flags & GIT_IDXENTRY_EXTENDED) {
2536
2562
  struct entry_long *ondisk_ext;
2537
2563
  ondisk_ext = (struct entry_long *)ondisk;
2538
- ondisk_ext->flags_extended = htons(entry->flags_extended);
2564
+ ondisk_ext->flags_extended = htons(entry->flags_extended &
2565
+ GIT_IDXENTRY_EXTENDED_FLAGS);
2539
2566
  path = ondisk_ext->path;
2540
2567
  }
2541
2568
  else
@@ -2718,6 +2745,15 @@ static int write_tree_extension(git_index *index, git_filebuf *file)
2718
2745
  return error;
2719
2746
  }
2720
2747
 
2748
+ static void clear_uptodate(git_index *index)
2749
+ {
2750
+ git_index_entry *entry;
2751
+ size_t i;
2752
+
2753
+ git_vector_foreach(&index->entries, i, entry)
2754
+ entry->flags_extended &= ~GIT_IDXENTRY_UPTODATE;
2755
+ }
2756
+
2721
2757
  static int write_index(git_oid *checksum, git_index *index, git_filebuf *file)
2722
2758
  {
2723
2759
  git_oid hash_final;
@@ -2757,7 +2793,13 @@ static int write_index(git_oid *checksum, git_index *index, git_filebuf *file)
2757
2793
  git_oid_cpy(checksum, &hash_final);
2758
2794
 
2759
2795
  /* write it at the end of the file */
2760
- return git_filebuf_write(file, hash_final.id, GIT_OID_RAWSZ);
2796
+ if (git_filebuf_write(file, hash_final.id, GIT_OID_RAWSZ) < 0)
2797
+ return -1;
2798
+
2799
+ /* file entries are no longer up to date */
2800
+ clear_uptodate(index);
2801
+
2802
+ return 0;
2761
2803
  }
2762
2804
 
2763
2805
  int git_index_entry_stage(const git_index_entry *entry)
@@ -2806,7 +2848,7 @@ static int read_tree_cb(
2806
2848
  entry->mode == old_entry->mode &&
2807
2849
  git_oid_equal(&entry->id, &old_entry->id))
2808
2850
  {
2809
- index_entry_cpy(entry, data->index, old_entry, false);
2851
+ index_entry_cpy(entry, old_entry);
2810
2852
  entry->flags_extended = 0;
2811
2853
  }
2812
2854
 
@@ -2924,14 +2966,17 @@ int git_index_read_index(
2924
2966
  (error = git_iterator_for_index(&new_iterator, (git_index *)new_index, &opts)) < 0)
2925
2967
  goto done;
2926
2968
 
2927
- if (((error = git_iterator_current(&old_entry, index_iterator)) < 0 &&
2969
+ if (((error = git_iterator_current(&old_entry, index_iterator)) < 0 &&
2928
2970
  error != GIT_ITEROVER) ||
2929
- ((error = git_iterator_current(&new_entry, new_iterator)) < 0 &&
2971
+ ((error = git_iterator_current(&new_entry, new_iterator)) < 0 &&
2930
2972
  error != GIT_ITEROVER))
2931
2973
  goto done;
2932
2974
 
2933
2975
  while (true) {
2934
- git_index_entry *add_entry = NULL, *remove_entry = NULL;
2976
+ git_index_entry
2977
+ *dup_entry = NULL,
2978
+ *add_entry = NULL,
2979
+ *remove_entry = NULL;
2935
2980
  int diff;
2936
2981
 
2937
2982
  if (old_entry && new_entry)
@@ -2946,8 +2991,7 @@ int git_index_read_index(
2946
2991
  if (diff < 0) {
2947
2992
  remove_entry = (git_index_entry *)old_entry;
2948
2993
  } else if (diff > 0) {
2949
- if ((error = index_entry_dup(&add_entry, index, new_entry)) < 0)
2950
- goto done;
2994
+ dup_entry = (git_index_entry *)new_entry;
2951
2995
  } else {
2952
2996
  /* Path and stage are equal, if the OID is equal, keep it to
2953
2997
  * keep the stat cache data.
@@ -2955,13 +2999,16 @@ int git_index_read_index(
2955
2999
  if (git_oid_equal(&old_entry->id, &new_entry->id)) {
2956
3000
  add_entry = (git_index_entry *)old_entry;
2957
3001
  } else {
2958
- if ((error = index_entry_dup(&add_entry, index, new_entry)) < 0)
2959
- goto done;
2960
-
3002
+ dup_entry = (git_index_entry *)new_entry;
2961
3003
  remove_entry = (git_index_entry *)old_entry;
2962
3004
  }
2963
3005
  }
2964
3006
 
3007
+ if (dup_entry) {
3008
+ if ((error = index_entry_dup_nocache(&add_entry, index, dup_entry)) < 0)
3009
+ goto done;
3010
+ }
3011
+
2965
3012
  if (add_entry) {
2966
3013
  if ((error = git_vector_insert(&new_entries, add_entry)) == 0)
2967
3014
  INSERT_IN_MAP_EX(index, new_entries_map, add_entry, error);
@@ -65,6 +65,45 @@ extern int git_index_entry_icmp(const void *a, const void *b);
65
65
  extern int git_index_entry_srch(const void *a, const void *b);
66
66
  extern int git_index_entry_isrch(const void *a, const void *b);
67
67
 
68
+ /* Index time handling functions */
69
+ GIT_INLINE(bool) git_index_time_eq(const git_index_time *one, const git_index_time *two)
70
+ {
71
+ if (one->seconds != two->seconds)
72
+ return false;
73
+
74
+ #ifdef GIT_USE_NSEC
75
+ if (one->nanoseconds != two->nanoseconds)
76
+ return false;
77
+ #endif
78
+
79
+ return true;
80
+ }
81
+
82
+ /*
83
+ * Test if the given index time is newer than the given existing index entry.
84
+ * If the timestamps are exactly equivalent, then the given index time is
85
+ * considered "racily newer" than the existing index entry.
86
+ */
87
+ GIT_INLINE(bool) git_index_entry_newer_than_index(
88
+ const git_index_entry *entry, git_index *index)
89
+ {
90
+ /* If we never read the index, we can't have this race either */
91
+ if (!index || index->stamp.mtime.tv_sec == 0)
92
+ return false;
93
+
94
+ /* If the timestamp is the same or newer than the index, it's racy */
95
+ #if defined(GIT_USE_NSEC)
96
+ if ((int32_t)index->stamp.tv_sec < entry->mtime.seconds)
97
+ return true;
98
+ else if ((int32_t)index->stamp.mtime.tv_sec > entry->mtime.seconds)
99
+ return false;
100
+ else
101
+ return (uint32_t)index->stamp.mtime.tv_nsec <= entry->mtime.nanoseconds;
102
+ #else
103
+ return ((int32_t)index->stamp.mtime.tv_sec) <= entry->mtime.seconds;
104
+ #endif
105
+ }
106
+
68
107
  /* Search index for `path`, returning GIT_ENOTFOUND if it does not exist
69
108
  * (but not setting an error message).
70
109
  *
@@ -27,6 +27,8 @@
27
27
  #include "config.h"
28
28
  #include "oidarray.h"
29
29
  #include "annotated_commit.h"
30
+ #include "commit.h"
31
+ #include "oidarray.h"
30
32
 
31
33
  #include "git2/types.h"
32
34
  #include "git2/repository.h"
@@ -47,6 +49,19 @@
47
49
  #define GIT_MERGE_INDEX_ENTRY_EXISTS(X) ((X).mode != 0)
48
50
  #define GIT_MERGE_INDEX_ENTRY_ISFILE(X) S_ISREG((X).mode)
49
51
 
52
+
53
+ /** Internal merge flags. */
54
+ enum {
55
+ /** The merge is for a virtual base in a recursive merge. */
56
+ GIT_MERGE__VIRTUAL_BASE = (1 << 31),
57
+ };
58
+
59
+ enum {
60
+ /** Accept the conflict file, staging it as the merge result. */
61
+ GIT_MERGE_FILE_FAVOR__CONFLICTED = 4,
62
+ };
63
+
64
+
50
65
  typedef enum {
51
66
  TREE_IDX_ANCESTOR = 0,
52
67
  TREE_IDX_OURS = 1,
@@ -799,11 +814,9 @@ static int merge_conflict_resolve_automerge(
799
814
  int *resolved,
800
815
  git_merge_diff_list *diff_list,
801
816
  const git_merge_diff *conflict,
802
- unsigned int merge_file_favor,
803
- unsigned int file_flags)
817
+ const git_merge_file_options *file_opts)
804
818
  {
805
819
  const git_index_entry *ancestor = NULL, *ours = NULL, *theirs = NULL;
806
- git_merge_file_options opts = GIT_MERGE_FILE_OPTIONS_INIT;
807
820
  git_merge_file_result result = {0};
808
821
  git_index_entry *index_entry;
809
822
  git_odb *odb = NULL;
@@ -850,12 +863,9 @@ static int merge_conflict_resolve_automerge(
850
863
  theirs = GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry) ?
851
864
  &conflict->their_entry : NULL;
852
865
 
853
- opts.favor = merge_file_favor;
854
- opts.flags = file_flags;
855
-
856
866
  if ((error = git_repository_odb(&odb, diff_list->repo)) < 0 ||
857
- (error = git_merge_file_from_index(&result, diff_list->repo, ancestor, ours, theirs, &opts)) < 0 ||
858
- !result.automergeable ||
867
+ (error = git_merge_file_from_index(&result, diff_list->repo, ancestor, ours, theirs, file_opts)) < 0 ||
868
+ (!result.automergeable && !(file_opts->flags & GIT_MERGE_FILE_FAVOR__CONFLICTED)) ||
859
869
  (error = git_odb_write(&automerge_oid, odb, result.ptr, result.len, GIT_OBJ_BLOB)) < 0)
860
870
  goto done;
861
871
 
@@ -885,8 +895,7 @@ static int merge_conflict_resolve(
885
895
  int *out,
886
896
  git_merge_diff_list *diff_list,
887
897
  const git_merge_diff *conflict,
888
- unsigned int merge_file_favor,
889
- unsigned int file_flags)
898
+ const git_merge_file_options *file_opts)
890
899
  {
891
900
  int resolved = 0;
892
901
  int error = 0;
@@ -902,8 +911,7 @@ static int merge_conflict_resolve(
902
911
  if (!resolved && (error = merge_conflict_resolve_one_renamed(&resolved, diff_list, conflict)) < 0)
903
912
  goto done;
904
913
 
905
- if (!resolved && (error = merge_conflict_resolve_automerge(&resolved, diff_list, conflict,
906
- merge_file_favor, file_flags)) < 0)
914
+ if (!resolved && (error = merge_conflict_resolve_automerge(&resolved, diff_list, conflict, file_opts)) < 0)
907
915
  goto done;
908
916
 
909
917
  *out = resolved;
@@ -1296,7 +1304,7 @@ int git_merge_diff_list__find_renames(
1296
1304
 
1297
1305
  assert(diff_list && opts);
1298
1306
 
1299
- if ((opts->tree_flags & GIT_MERGE_TREE_FIND_RENAMES) == 0)
1307
+ if ((opts->flags & GIT_MERGE_FIND_RENAMES) == 0)
1300
1308
  return 0;
1301
1309
 
1302
1310
  similarity_ours = git__calloc(diff_list->conflicts.length,
@@ -1632,8 +1640,8 @@ static int merge_normalize_opts(
1632
1640
  git_merge_options init = GIT_MERGE_OPTIONS_INIT;
1633
1641
  memcpy(opts, &init, sizeof(init));
1634
1642
 
1635
- opts->tree_flags = GIT_MERGE_TREE_FIND_RENAMES;
1636
- opts->rename_threshold = GIT_MERGE_TREE_RENAME_THRESHOLD;
1643
+ opts->flags = GIT_MERGE_FIND_RENAMES;
1644
+ opts->rename_threshold = GIT_MERGE_DEFAULT_RENAME_THRESHOLD;
1637
1645
  }
1638
1646
 
1639
1647
  if (!opts->target_limit) {
@@ -1643,7 +1651,7 @@ static int merge_normalize_opts(
1643
1651
  limit = git_config__get_int_force(cfg, "diff.renamelimit", 0);
1644
1652
 
1645
1653
  opts->target_limit = (limit <= 0) ?
1646
- GIT_MERGE_TREE_TARGET_LIMIT : (unsigned int)limit;
1654
+ GIT_MERGE_DEFAULT_TARGET_LIMIT : (unsigned int)limit;
1647
1655
  }
1648
1656
 
1649
1657
  /* assign the internal metric with whitespace flag as payload */
@@ -1827,6 +1835,7 @@ int git_merge__iterators(
1827
1835
  *empty_theirs = NULL;
1828
1836
  git_merge_diff_list *diff_list;
1829
1837
  git_merge_options opts;
1838
+ git_merge_file_options file_opts = GIT_MERGE_FILE_OPTIONS_INIT;
1830
1839
  git_merge_diff *conflict;
1831
1840
  git_vector changes;
1832
1841
  size_t i;
@@ -1842,6 +1851,17 @@ int git_merge__iterators(
1842
1851
  if ((error = merge_normalize_opts(repo, &opts, given_opts)) < 0)
1843
1852
  return error;
1844
1853
 
1854
+ file_opts.favor = opts.file_favor;
1855
+ file_opts.flags = opts.file_flags;
1856
+
1857
+ /* use the git-inspired labels when virtual base building */
1858
+ if (opts.flags & GIT_MERGE__VIRTUAL_BASE) {
1859
+ file_opts.ancestor_label = "merged common ancestors";
1860
+ file_opts.our_label = "Temporary merge branch 1";
1861
+ file_opts.their_label = "Temporary merge branch 2";
1862
+ file_opts.flags |= GIT_MERGE_FILE_FAVOR__CONFLICTED;
1863
+ }
1864
+
1845
1865
  diff_list = git_merge_diff_list__alloc(repo);
1846
1866
  GITERR_CHECK_ALLOC(diff_list);
1847
1867
 
@@ -1860,11 +1880,12 @@ int git_merge__iterators(
1860
1880
  git_vector_foreach(&changes, i, conflict) {
1861
1881
  int resolved = 0;
1862
1882
 
1863
- if ((error = merge_conflict_resolve(&resolved, diff_list, conflict, opts.file_favor, opts.file_flags)) < 0)
1883
+ if ((error = merge_conflict_resolve(
1884
+ &resolved, diff_list, conflict, &file_opts)) < 0)
1864
1885
  goto done;
1865
1886
 
1866
1887
  if (!resolved) {
1867
- if ((opts.tree_flags & GIT_MERGE_TREE_FAIL_ON_CONFLICT)) {
1888
+ if ((opts.flags & GIT_MERGE_FAIL_ON_CONFLICT)) {
1868
1889
  giterr_set(GITERR_MERGE, "merge conflicts exist");
1869
1890
  error = GIT_EMERGECONFLICT;
1870
1891
  goto done;
@@ -1875,7 +1896,7 @@ int git_merge__iterators(
1875
1896
  }
1876
1897
 
1877
1898
  error = index_from_diff_list(out, diff_list,
1878
- (opts.tree_flags & GIT_MERGE_TREE_SKIP_REUC));
1899
+ (opts.flags & GIT_MERGE_SKIP_REUC));
1879
1900
 
1880
1901
  done:
1881
1902
  if (!given_opts || !given_opts->metric)
@@ -1922,6 +1943,207 @@ done:
1922
1943
  return error;
1923
1944
  }
1924
1945
 
1946
+ static int merge_annotated_commits(
1947
+ git_index **index_out,
1948
+ git_annotated_commit **base_out,
1949
+ git_repository *repo,
1950
+ git_annotated_commit *our_commit,
1951
+ git_annotated_commit *their_commit,
1952
+ size_t recursion_level,
1953
+ const git_merge_options *opts);
1954
+
1955
+ GIT_INLINE(int) insert_head_ids(
1956
+ git_array_oid_t *ids,
1957
+ const git_annotated_commit *annotated_commit)
1958
+ {
1959
+ git_oid *id;
1960
+ size_t i;
1961
+
1962
+ if (annotated_commit->type == GIT_ANNOTATED_COMMIT_REAL) {
1963
+ id = git_array_alloc(*ids);
1964
+ GITERR_CHECK_ALLOC(id);
1965
+
1966
+ git_oid_cpy(id, git_commit_id(annotated_commit->commit));
1967
+ } else {
1968
+ for (i = 0; i < annotated_commit->parents.size; i++) {
1969
+ id = git_array_alloc(*ids);
1970
+ GITERR_CHECK_ALLOC(id);
1971
+
1972
+ git_oid_cpy(id, &annotated_commit->parents.ptr[i]);
1973
+ }
1974
+ }
1975
+
1976
+ return 0;
1977
+ }
1978
+
1979
+ static int create_virtual_base(
1980
+ git_annotated_commit **out,
1981
+ git_repository *repo,
1982
+ git_annotated_commit *one,
1983
+ git_annotated_commit *two,
1984
+ const git_merge_options *opts,
1985
+ size_t recursion_level)
1986
+ {
1987
+ git_annotated_commit *result = NULL;
1988
+ git_index *index = NULL;
1989
+ git_merge_options virtual_opts = GIT_MERGE_OPTIONS_INIT;
1990
+
1991
+ result = git__calloc(1, sizeof(git_annotated_commit));
1992
+ GITERR_CHECK_ALLOC(result);
1993
+
1994
+ /* Conflicts in the merge base creation do not propagate to conflicts
1995
+ * in the result; the conflicted base will act as the common ancestor.
1996
+ */
1997
+ if (opts)
1998
+ memcpy(&virtual_opts, opts, sizeof(git_merge_options));
1999
+
2000
+ virtual_opts.flags &= ~GIT_MERGE_FAIL_ON_CONFLICT;
2001
+ virtual_opts.flags |= GIT_MERGE__VIRTUAL_BASE;
2002
+
2003
+ if ((merge_annotated_commits(&index, NULL, repo, one, two,
2004
+ recursion_level + 1, &virtual_opts)) < 0)
2005
+ return -1;
2006
+
2007
+ result->type = GIT_ANNOTATED_COMMIT_VIRTUAL;
2008
+ result->index = index;
2009
+
2010
+ insert_head_ids(&result->parents, one);
2011
+ insert_head_ids(&result->parents, two);
2012
+
2013
+ *out = result;
2014
+ return 0;
2015
+ }
2016
+
2017
+ static int compute_base(
2018
+ git_annotated_commit **out,
2019
+ git_repository *repo,
2020
+ const git_annotated_commit *one,
2021
+ const git_annotated_commit *two,
2022
+ const git_merge_options *given_opts,
2023
+ size_t recursion_level)
2024
+ {
2025
+ git_array_oid_t head_ids = GIT_ARRAY_INIT;
2026
+ git_oidarray bases = {0};
2027
+ git_annotated_commit *base = NULL, *other = NULL, *new_base = NULL;
2028
+ git_merge_options opts = GIT_MERGE_OPTIONS_INIT;
2029
+ size_t i;
2030
+ int error;
2031
+
2032
+ *out = NULL;
2033
+
2034
+ if (given_opts)
2035
+ memcpy(&opts, given_opts, sizeof(git_merge_options));
2036
+
2037
+ if ((error = insert_head_ids(&head_ids, one)) < 0 ||
2038
+ (error = insert_head_ids(&head_ids, two)) < 0)
2039
+ goto done;
2040
+
2041
+ if ((error = git_merge_bases_many(&bases, repo,
2042
+ head_ids.size, head_ids.ptr)) < 0 ||
2043
+ (error = git_annotated_commit_lookup(&base, repo, &bases.ids[0])) < 0 ||
2044
+ (opts.flags & GIT_MERGE_NO_RECURSIVE))
2045
+ goto done;
2046
+
2047
+ for (i = 1; i < bases.count; i++) {
2048
+ recursion_level++;
2049
+
2050
+ if (opts.recursion_limit && recursion_level > opts.recursion_limit)
2051
+ break;
2052
+
2053
+ if ((error = git_annotated_commit_lookup(&other, repo,
2054
+ &bases.ids[i])) < 0 ||
2055
+ (error = create_virtual_base(&new_base, repo, base, other, &opts,
2056
+ recursion_level)) < 0)
2057
+ goto done;
2058
+
2059
+ git_annotated_commit_free(base);
2060
+ git_annotated_commit_free(other);
2061
+
2062
+ base = new_base;
2063
+ new_base = NULL;
2064
+ other = NULL;
2065
+ }
2066
+
2067
+ done:
2068
+ if (error == 0)
2069
+ *out = base;
2070
+ else
2071
+ git_annotated_commit_free(base);
2072
+
2073
+ git_annotated_commit_free(other);
2074
+ git_annotated_commit_free(new_base);
2075
+ git_oidarray_free(&bases);
2076
+ git_array_clear(head_ids);
2077
+ return error;
2078
+ }
2079
+
2080
+ static int iterator_for_annotated_commit(
2081
+ git_iterator **out,
2082
+ git_annotated_commit *commit)
2083
+ {
2084
+ git_iterator_options opts = GIT_ITERATOR_OPTIONS_INIT;
2085
+ int error;
2086
+
2087
+ opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;
2088
+
2089
+ if (commit == NULL) {
2090
+ error = git_iterator_for_nothing(out, &opts);
2091
+ } else if (commit->type == GIT_ANNOTATED_COMMIT_VIRTUAL) {
2092
+ error = git_iterator_for_index(out, commit->index, &opts);
2093
+ } else {
2094
+ if (!commit->tree &&
2095
+ (error = git_commit_tree(&commit->tree, commit->commit)) < 0)
2096
+ goto done;
2097
+
2098
+ error = git_iterator_for_tree(out, commit->tree, &opts);
2099
+ }
2100
+
2101
+ done:
2102
+ return error;
2103
+ }
2104
+
2105
+ static int merge_annotated_commits(
2106
+ git_index **index_out,
2107
+ git_annotated_commit **base_out,
2108
+ git_repository *repo,
2109
+ git_annotated_commit *ours,
2110
+ git_annotated_commit *theirs,
2111
+ size_t recursion_level,
2112
+ const git_merge_options *opts)
2113
+ {
2114
+ git_annotated_commit *base = NULL;
2115
+ git_iterator *base_iter = NULL, *our_iter = NULL, *their_iter = NULL;
2116
+ int error;
2117
+
2118
+ if ((error = compute_base(&base, repo, ours, theirs, opts,
2119
+ recursion_level)) < 0) {
2120
+
2121
+ if (error != GIT_ENOTFOUND)
2122
+ goto done;
2123
+
2124
+ giterr_clear();
2125
+ }
2126
+
2127
+ if ((error = iterator_for_annotated_commit(&base_iter, base)) < 0 ||
2128
+ (error = iterator_for_annotated_commit(&our_iter, ours)) < 0 ||
2129
+ (error = iterator_for_annotated_commit(&their_iter, theirs)) < 0 ||
2130
+ (error = git_merge__iterators(index_out, repo, base_iter, our_iter,
2131
+ their_iter, opts)) < 0)
2132
+ goto done;
2133
+
2134
+ if (base_out) {
2135
+ *base_out = base;
2136
+ base = NULL;
2137
+ }
2138
+
2139
+ done:
2140
+ git_annotated_commit_free(base);
2141
+ git_iterator_free(base_iter);
2142
+ git_iterator_free(our_iter);
2143
+ git_iterator_free(their_iter);
2144
+ return error;
2145
+ }
2146
+
1925
2147
 
1926
2148
  int git_merge_commits(
1927
2149
  git_index **out,
@@ -1930,30 +2152,19 @@ int git_merge_commits(
1930
2152
  const git_commit *their_commit,
1931
2153
  const git_merge_options *opts)
1932
2154
  {
1933
- git_oid ancestor_oid;
1934
- git_commit *ancestor_commit = NULL;
1935
- git_tree *our_tree = NULL, *their_tree = NULL, *ancestor_tree = NULL;
2155
+ git_annotated_commit *ours = NULL, *theirs = NULL, *base = NULL;
1936
2156
  int error = 0;
1937
2157
 
1938
- if ((error = git_merge_base(&ancestor_oid, repo, git_commit_id(our_commit), git_commit_id(their_commit))) < 0 &&
1939
- error == GIT_ENOTFOUND)
1940
- giterr_clear();
1941
- else if (error < 0 ||
1942
- (error = git_commit_lookup(&ancestor_commit, repo, &ancestor_oid)) < 0 ||
1943
- (error = git_commit_tree(&ancestor_tree, ancestor_commit)) < 0)
2158
+ if ((error = git_annotated_commit_from_commit(&ours, (git_commit *)our_commit)) < 0 ||
2159
+ (error = git_annotated_commit_from_commit(&theirs, (git_commit *)their_commit)) < 0)
1944
2160
  goto done;
1945
2161
 
1946
- if ((error = git_commit_tree(&our_tree, our_commit)) < 0 ||
1947
- (error = git_commit_tree(&their_tree, their_commit)) < 0 ||
1948
- (error = git_merge_trees(out, repo, ancestor_tree, our_tree, their_tree, opts)) < 0)
1949
- goto done;
2162
+ error = merge_annotated_commits(out, &base, repo, ours, theirs, 0, opts);
1950
2163
 
1951
2164
  done:
1952
- git_commit_free(ancestor_commit);
1953
- git_tree_free(our_tree);
1954
- git_tree_free(their_tree);
1955
- git_tree_free(ancestor_tree);
1956
-
2165
+ git_annotated_commit_free(ours);
2166
+ git_annotated_commit_free(theirs);
2167
+ git_annotated_commit_free(base);
1957
2168
  return error;
1958
2169
  }
1959
2170
 
@@ -2387,49 +2598,50 @@ const char *merge_their_label(const char *branchname)
2387
2598
  }
2388
2599
 
2389
2600
  static int merge_normalize_checkout_opts(
2601
+ git_checkout_options *out,
2390
2602
  git_repository *repo,
2391
- git_checkout_options *checkout_opts,
2392
2603
  const git_checkout_options *given_checkout_opts,
2393
- const git_annotated_commit *ancestor_head,
2604
+ unsigned int checkout_strategy,
2605
+ git_annotated_commit *ancestor,
2394
2606
  const git_annotated_commit *our_head,
2395
- size_t their_heads_len,
2396
- const git_annotated_commit **their_heads)
2607
+ const git_annotated_commit **their_heads,
2608
+ size_t their_heads_len)
2397
2609
  {
2610
+ git_checkout_options default_checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
2398
2611
  int error = 0;
2399
2612
 
2400
2613
  GIT_UNUSED(repo);
2401
2614
 
2402
2615
  if (given_checkout_opts != NULL)
2403
- memcpy(checkout_opts, given_checkout_opts, sizeof(git_checkout_options));
2404
- else {
2405
- git_checkout_options default_checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
2406
- default_checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
2616
+ memcpy(out, given_checkout_opts, sizeof(git_checkout_options));
2617
+ else
2618
+ memcpy(out, &default_checkout_opts, sizeof(git_checkout_options));
2407
2619
 
2408
- memcpy(checkout_opts, &default_checkout_opts, sizeof(git_checkout_options));
2409
- }
2620
+ out->checkout_strategy = checkout_strategy;
2410
2621
 
2411
- /* TODO: for multiple ancestors in merge-recursive, this is "merged common ancestors" */
2412
- if (!checkout_opts->ancestor_label) {
2413
- if (ancestor_head && ancestor_head->commit)
2414
- checkout_opts->ancestor_label = git_commit_summary(ancestor_head->commit);
2622
+ if (!out->ancestor_label) {
2623
+ if (ancestor && ancestor->type == GIT_ANNOTATED_COMMIT_REAL)
2624
+ out->ancestor_label = git_commit_summary(ancestor->commit);
2625
+ else if (ancestor)
2626
+ out->ancestor_label = "merged common ancestors";
2415
2627
  else
2416
- checkout_opts->ancestor_label = "ancestor";
2628
+ out->ancestor_label = "empty base";
2417
2629
  }
2418
2630
 
2419
- if (!checkout_opts->our_label) {
2631
+ if (!out->our_label) {
2420
2632
  if (our_head && our_head->ref_name)
2421
- checkout_opts->our_label = our_head->ref_name;
2633
+ out->our_label = our_head->ref_name;
2422
2634
  else
2423
- checkout_opts->our_label = "ours";
2635
+ out->our_label = "ours";
2424
2636
  }
2425
2637
 
2426
- if (!checkout_opts->their_label) {
2638
+ if (!out->their_label) {
2427
2639
  if (their_heads_len == 1 && their_heads[0]->ref_name)
2428
- checkout_opts->their_label = merge_their_label(their_heads[0]->ref_name);
2640
+ out->their_label = merge_their_label(their_heads[0]->ref_name);
2429
2641
  else if (their_heads_len == 1)
2430
- checkout_opts->their_label = their_heads[0]->id_str;
2642
+ out->their_label = their_heads[0]->id_str;
2431
2643
  else
2432
- checkout_opts->their_label = "theirs";
2644
+ out->their_label = "theirs";
2433
2645
  }
2434
2646
 
2435
2647
  return error;
@@ -2782,11 +2994,10 @@ int git_merge(
2782
2994
  {
2783
2995
  git_reference *our_ref = NULL;
2784
2996
  git_checkout_options checkout_opts;
2785
- git_annotated_commit *ancestor_head = NULL, *our_head = NULL;
2786
- git_tree *ancestor_tree = NULL, *our_tree = NULL, **their_trees = NULL;
2997
+ git_annotated_commit *our_head = NULL, *base = NULL;
2787
2998
  git_index *index = NULL;
2788
2999
  git_indexwriter indexwriter = GIT_INDEXWRITER_INIT;
2789
- size_t i;
3000
+ unsigned int checkout_strategy;
2790
3001
  int error = 0;
2791
3002
 
2792
3003
  assert(repo && their_heads);
@@ -2796,61 +3007,49 @@ int git_merge(
2796
3007
  return -1;
2797
3008
  }
2798
3009
 
2799
- their_trees = git__calloc(their_heads_len, sizeof(git_tree *));
2800
- GITERR_CHECK_ALLOC(their_trees);
2801
-
2802
- if ((error = merge_heads(&ancestor_head, &our_head, repo, their_heads, their_heads_len)) < 0 ||
2803
- (error = merge_normalize_checkout_opts(repo, &checkout_opts, given_checkout_opts,
2804
- ancestor_head, our_head, their_heads_len, their_heads)) < 0 ||
2805
- (error = git_indexwriter_init_for_operation(&indexwriter, repo, &checkout_opts.checkout_strategy)) < 0)
2806
- goto on_error;
2807
-
2808
- /* Write the merge files to the repository. */
2809
- if ((error = git_merge__setup(repo, our_head, their_heads, their_heads_len)) < 0)
2810
- goto on_error;
3010
+ if ((error = git_repository__ensure_not_bare(repo, "merge")) < 0)
3011
+ goto done;
2811
3012
 
2812
- if (ancestor_head != NULL &&
2813
- (error = git_commit_tree(&ancestor_tree, ancestor_head->commit)) < 0)
2814
- goto on_error;
3013
+ checkout_strategy = given_checkout_opts ?
3014
+ given_checkout_opts->checkout_strategy :
3015
+ GIT_CHECKOUT_SAFE;
2815
3016
 
2816
- if ((error = git_commit_tree(&our_tree, our_head->commit)) < 0)
2817
- goto on_error;
3017
+ if ((error = git_indexwriter_init_for_operation(&indexwriter, repo,
3018
+ &checkout_strategy)) < 0)
3019
+ goto done;
2818
3020
 
2819
- for (i = 0; i < their_heads_len; i++) {
2820
- if ((error = git_commit_tree(&their_trees[i], their_heads[i]->commit)) < 0)
2821
- goto on_error;
2822
- }
3021
+ /* Write the merge setup files to the repository. */
3022
+ if ((error = git_annotated_commit_from_head(&our_head, repo)) < 0 ||
3023
+ (error = git_merge__setup(repo, our_head, their_heads,
3024
+ their_heads_len)) < 0)
3025
+ goto done;
2823
3026
 
2824
- /* TODO: recursive, octopus, etc... */
3027
+ /* TODO: octopus */
2825
3028
 
2826
- if ((error = git_merge_trees(&index, repo, ancestor_tree, our_tree, their_trees[0], merge_opts)) < 0 ||
3029
+ if ((error = merge_annotated_commits(&index, &base, repo, our_head,
3030
+ (git_annotated_commit *)their_heads[0], 0, merge_opts)) < 0 ||
2827
3031
  (error = git_merge__check_result(repo, index)) < 0 ||
2828
- (error = git_merge__append_conflicts_to_merge_msg(repo, index)) < 0 ||
2829
- (error = git_checkout_index(repo, index, &checkout_opts)) < 0 ||
2830
- (error = git_indexwriter_commit(&indexwriter)) < 0)
2831
- goto on_error;
3032
+ (error = git_merge__append_conflicts_to_merge_msg(repo, index)) < 0)
3033
+ goto done;
2832
3034
 
2833
- goto done;
3035
+ /* check out the merge results */
2834
3036
 
2835
- on_error:
2836
- merge_state_cleanup(repo);
3037
+ if ((error = merge_normalize_checkout_opts(&checkout_opts, repo,
3038
+ given_checkout_opts, checkout_strategy,
3039
+ base, our_head, their_heads, their_heads_len)) < 0 ||
3040
+ (error = git_checkout_index(repo, index, &checkout_opts)) < 0)
3041
+ goto done;
3042
+
3043
+ error = git_indexwriter_commit(&indexwriter);
2837
3044
 
2838
3045
  done:
2839
- git_indexwriter_cleanup(&indexwriter);
3046
+ if (error < 0)
3047
+ merge_state_cleanup(repo);
2840
3048
 
3049
+ git_indexwriter_cleanup(&indexwriter);
2841
3050
  git_index_free(index);
2842
-
2843
- git_tree_free(ancestor_tree);
2844
- git_tree_free(our_tree);
2845
-
2846
- for (i = 0; i < their_heads_len; i++)
2847
- git_tree_free(their_trees[i]);
2848
-
2849
- git__free(their_trees);
2850
-
2851
3051
  git_annotated_commit_free(our_head);
2852
- git_annotated_commit_free(ancestor_head);
2853
-
3052
+ git_annotated_commit_free(base);
2854
3053
  git_reference_free(our_ref);
2855
3054
 
2856
3055
  return error;