rugged 0.22.2 → 0.23.0b1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (155) hide show
  1. checksums.yaml +4 -4
  2. data/ext/rugged/rugged.c +1 -2
  3. data/ext/rugged/rugged_branch_collection.c +6 -44
  4. data/ext/rugged/rugged_config.c +7 -3
  5. data/ext/rugged/rugged_diff_delta.c +1 -1
  6. data/ext/rugged/rugged_diff_line.c +1 -1
  7. data/ext/rugged/rugged_object.c +2 -2
  8. data/ext/rugged/rugged_reference_collection.c +12 -56
  9. data/ext/rugged/rugged_remote.c +4 -33
  10. data/ext/rugged/rugged_remote_collection.c +1 -1
  11. data/ext/rugged/rugged_repo.c +10 -36
  12. data/ext/rugged/rugged_settings.c +3 -3
  13. data/ext/rugged/rugged_tree.c +1 -1
  14. data/lib/rugged/version.rb +1 -1
  15. data/vendor/libgit2/CMakeLists.txt +10 -3
  16. data/vendor/libgit2/COPYING +15 -21
  17. data/vendor/libgit2/include/git2/annotated_commit.h +20 -3
  18. data/vendor/libgit2/include/git2/branch.h +20 -16
  19. data/vendor/libgit2/include/git2/checkout.h +32 -18
  20. data/vendor/libgit2/include/git2/cherrypick.h +2 -2
  21. data/vendor/libgit2/include/git2/clone.h +4 -10
  22. data/vendor/libgit2/include/git2/config.h +66 -12
  23. data/vendor/libgit2/include/git2/describe.h +3 -2
  24. data/vendor/libgit2/include/git2/diff.h +3 -3
  25. data/vendor/libgit2/include/git2/errors.h +1 -0
  26. data/vendor/libgit2/include/git2/filter.h +21 -5
  27. data/vendor/libgit2/include/git2/index.h +32 -0
  28. data/vendor/libgit2/include/git2/merge.h +20 -3
  29. data/vendor/libgit2/include/git2/oid.h +1 -1
  30. data/vendor/libgit2/include/git2/pack.h +13 -0
  31. data/vendor/libgit2/include/git2/patch.h +3 -6
  32. data/vendor/libgit2/include/git2/rebase.h +8 -12
  33. data/vendor/libgit2/include/git2/refs.h +19 -29
  34. data/vendor/libgit2/include/git2/remote.h +5 -11
  35. data/vendor/libgit2/include/git2/repository.h +44 -15
  36. data/vendor/libgit2/include/git2/reset.h +19 -10
  37. data/vendor/libgit2/include/git2/revert.h +2 -2
  38. data/vendor/libgit2/include/git2/submodule.h +3 -9
  39. data/vendor/libgit2/include/git2/sys/config.h +3 -1
  40. data/vendor/libgit2/include/git2/sys/filter.h +10 -2
  41. data/vendor/libgit2/include/git2/sys/hashsig.h +49 -22
  42. data/vendor/libgit2/include/git2/transport.h +1 -1
  43. data/vendor/libgit2/include/git2/types.h +10 -3
  44. data/vendor/libgit2/include/git2/version.h +3 -2
  45. data/vendor/libgit2/src/annotated_commit.c +28 -0
  46. data/vendor/libgit2/src/array.h +19 -8
  47. data/vendor/libgit2/src/attr.c +95 -35
  48. data/vendor/libgit2/src/attr_file.c +51 -17
  49. data/vendor/libgit2/src/attr_file.h +37 -10
  50. data/vendor/libgit2/src/attrcache.c +13 -7
  51. data/vendor/libgit2/src/attrcache.h +1 -0
  52. data/vendor/libgit2/src/blame.c +26 -2
  53. data/vendor/libgit2/src/blame_git.c +6 -2
  54. data/vendor/libgit2/src/blob.c +6 -8
  55. data/vendor/libgit2/src/branch.c +55 -43
  56. data/vendor/libgit2/src/buf_text.c +13 -6
  57. data/vendor/libgit2/src/buffer.c +110 -25
  58. data/vendor/libgit2/src/buffer.h +18 -0
  59. data/vendor/libgit2/src/checkout.c +164 -92
  60. data/vendor/libgit2/src/checkout.h +0 -7
  61. data/vendor/libgit2/src/cherrypick.c +13 -7
  62. data/vendor/libgit2/src/clone.c +23 -25
  63. data/vendor/libgit2/src/commit.c +3 -3
  64. data/vendor/libgit2/src/common.h +23 -1
  65. data/vendor/libgit2/src/config.c +137 -19
  66. data/vendor/libgit2/src/config.h +2 -2
  67. data/vendor/libgit2/src/config_cache.c +2 -1
  68. data/vendor/libgit2/src/config_file.c +39 -18
  69. data/vendor/libgit2/src/config_file.h +1 -1
  70. data/vendor/libgit2/src/crlf.c +1 -1
  71. data/vendor/libgit2/src/delta-apply.c +3 -2
  72. data/vendor/libgit2/src/delta.c +25 -6
  73. data/vendor/libgit2/src/describe.c +2 -0
  74. data/vendor/libgit2/src/diff.c +8 -5
  75. data/vendor/libgit2/src/diff_driver.c +39 -18
  76. data/vendor/libgit2/src/diff_file.c +1 -1
  77. data/vendor/libgit2/src/diff_patch.c +12 -6
  78. data/vendor/libgit2/src/diff_tform.c +21 -24
  79. data/vendor/libgit2/src/filebuf.c +14 -12
  80. data/vendor/libgit2/src/fileops.c +61 -18
  81. data/vendor/libgit2/src/fileops.h +11 -2
  82. data/vendor/libgit2/src/filter.c +351 -99
  83. data/vendor/libgit2/src/filter.h +17 -0
  84. data/vendor/libgit2/src/global.c +38 -9
  85. data/vendor/libgit2/src/hash/hash_generic.c +1 -1
  86. data/vendor/libgit2/src/hashsig.c +28 -16
  87. data/vendor/libgit2/src/ignore.c +2 -2
  88. data/vendor/libgit2/src/index.c +159 -42
  89. data/vendor/libgit2/src/index.h +29 -0
  90. data/vendor/libgit2/src/indexer.c +11 -2
  91. data/vendor/libgit2/src/integer.h +96 -0
  92. data/vendor/libgit2/src/iterator.c +5 -3
  93. data/vendor/libgit2/src/khash.h +41 -29
  94. data/vendor/libgit2/src/merge.c +48 -35
  95. data/vendor/libgit2/src/merge.h +0 -1
  96. data/vendor/libgit2/src/merge_file.c +13 -0
  97. data/vendor/libgit2/src/mwindow.c +1 -1
  98. data/vendor/libgit2/src/notes.c +1 -1
  99. data/vendor/libgit2/src/odb.c +13 -11
  100. data/vendor/libgit2/src/odb_loose.c +22 -10
  101. data/vendor/libgit2/src/odb_mempack.c +4 -2
  102. data/vendor/libgit2/src/offmap.h +3 -2
  103. data/vendor/libgit2/src/oid.c +1 -1
  104. data/vendor/libgit2/src/oidmap.h +2 -1
  105. data/vendor/libgit2/src/openssl_stream.c +6 -3
  106. data/vendor/libgit2/src/pack-objects.c +273 -12
  107. data/vendor/libgit2/src/pack-objects.h +10 -0
  108. data/vendor/libgit2/src/pack.c +17 -6
  109. data/vendor/libgit2/src/pack.h +1 -3
  110. data/vendor/libgit2/src/path.c +68 -38
  111. data/vendor/libgit2/src/pathspec.c +3 -0
  112. data/vendor/libgit2/src/pool.c +9 -8
  113. data/vendor/libgit2/src/posix.c +11 -1
  114. data/vendor/libgit2/src/push.c +15 -17
  115. data/vendor/libgit2/src/push.h +1 -6
  116. data/vendor/libgit2/src/rebase.c +77 -35
  117. data/vendor/libgit2/src/refdb_fs.c +2 -2
  118. data/vendor/libgit2/src/refs.c +107 -81
  119. data/vendor/libgit2/src/refs.h +2 -2
  120. data/vendor/libgit2/src/refspec.c +3 -0
  121. data/vendor/libgit2/src/remote.c +19 -21
  122. data/vendor/libgit2/src/repository.c +258 -67
  123. data/vendor/libgit2/src/repository.h +31 -16
  124. data/vendor/libgit2/src/reset.c +28 -12
  125. data/vendor/libgit2/src/revert.c +12 -7
  126. data/vendor/libgit2/src/revwalk.c +3 -5
  127. data/vendor/libgit2/src/revwalk.h +1 -1
  128. data/vendor/libgit2/src/sortedcache.c +5 -3
  129. data/vendor/libgit2/src/stash.c +3 -5
  130. data/vendor/libgit2/src/strmap.h +2 -1
  131. data/vendor/libgit2/src/submodule.c +5 -6
  132. data/vendor/libgit2/src/tag.c +7 -5
  133. data/vendor/libgit2/src/transaction.c +1 -1
  134. data/vendor/libgit2/src/transports/cred.c +5 -2
  135. data/vendor/libgit2/src/transports/git.c +2 -3
  136. data/vendor/libgit2/src/transports/local.c +15 -34
  137. data/vendor/libgit2/src/transports/smart.c +1 -1
  138. data/vendor/libgit2/src/transports/smart_pkt.c +58 -18
  139. data/vendor/libgit2/src/transports/smart_protocol.c +2 -2
  140. data/vendor/libgit2/src/transports/winhttp.c +2 -2
  141. data/vendor/libgit2/src/tree.c +7 -5
  142. data/vendor/libgit2/src/tsort.c +3 -1
  143. data/vendor/libgit2/src/util.c +25 -0
  144. data/vendor/libgit2/src/util.h +31 -27
  145. data/vendor/libgit2/src/vector.c +2 -7
  146. data/vendor/libgit2/src/win32/dir.c +5 -3
  147. data/vendor/libgit2/src/win32/git2.rc +8 -4
  148. data/vendor/libgit2/src/win32/mingw-compat.h +7 -0
  149. data/vendor/libgit2/src/win32/msvc-compat.h +3 -0
  150. data/vendor/libgit2/src/win32/posix.h +1 -3
  151. data/vendor/libgit2/src/win32/posix_w32.c +31 -7
  152. data/vendor/libgit2/src/win32/utf-conv.c +1 -3
  153. data/vendor/libgit2/src/zstream.c +1 -1
  154. metadata +5 -5
  155. data/vendor/libgit2/src/bswap.h +0 -97
@@ -26,6 +26,7 @@
26
26
  #include "remote.h"
27
27
  #include "merge.h"
28
28
  #include "diff_driver.h"
29
+ #include "annotated_commit.h"
29
30
 
30
31
  #ifdef GIT_WIN32
31
32
  # include "win32/w32_util.h"
@@ -37,8 +38,16 @@
37
38
 
38
39
  #define GIT_REPO_VERSION 0
39
40
 
40
- const char *git_repository__8dot3_default = "GIT~1";
41
- size_t git_repository__8dot3_default_len = 5;
41
+ git_buf git_repository__reserved_names_win32[] = {
42
+ { DOT_GIT, 0, CONST_STRLEN(DOT_GIT) },
43
+ { GIT_DIR_SHORTNAME, 0, CONST_STRLEN(GIT_DIR_SHORTNAME) }
44
+ };
45
+ size_t git_repository__reserved_names_win32_len = 2;
46
+
47
+ git_buf git_repository__reserved_names_posix[] = {
48
+ { DOT_GIT, 0, CONST_STRLEN(DOT_GIT) },
49
+ };
50
+ size_t git_repository__reserved_names_posix_len = 1;
42
51
 
43
52
  static void set_odb(git_repository *repo, git_odb *odb)
44
53
  {
@@ -110,6 +119,8 @@ void git_repository__cleanup(git_repository *repo)
110
119
 
111
120
  void git_repository_free(git_repository *repo)
112
121
  {
122
+ size_t i;
123
+
113
124
  if (repo == NULL)
114
125
  return;
115
126
 
@@ -120,10 +131,14 @@ void git_repository_free(git_repository *repo)
120
131
  git_diff_driver_registry_free(repo->diff_drivers);
121
132
  repo->diff_drivers = NULL;
122
133
 
134
+ for (i = 0; i < repo->reserved_names.size; i++)
135
+ git_buf_free(git_array_get(repo->reserved_names, i));
136
+
123
137
  git__free(repo->path_repository);
124
138
  git__free(repo->workdir);
125
139
  git__free(repo->namespace);
126
- git__free(repo->name_8dot3);
140
+ git__free(repo->ident_name);
141
+ git__free(repo->ident_email);
127
142
 
128
143
  git__memzero(repo, sizeof(*repo));
129
144
  git__free(repo);
@@ -153,23 +168,37 @@ static bool valid_repository_path(git_buf *repository_path)
153
168
  static git_repository *repository_alloc(void)
154
169
  {
155
170
  git_repository *repo = git__calloc(1, sizeof(git_repository));
156
- if (!repo)
157
- return NULL;
158
171
 
159
- if (git_cache_init(&repo->objects) < 0) {
160
- git__free(repo);
161
- return NULL;
162
- }
172
+ if (repo == NULL ||
173
+ git_cache_init(&repo->objects) < 0)
174
+ goto on_error;
175
+
176
+ git_array_init_to_size(repo->reserved_names, 4);
177
+ if (!repo->reserved_names.ptr)
178
+ goto on_error;
163
179
 
164
180
  /* set all the entries in the cvar cache to `unset` */
165
181
  git_repository__cvar_cache_clear(repo);
166
182
 
167
183
  return repo;
184
+
185
+ on_error:
186
+ if (repo)
187
+ git_cache_free(&repo->objects);
188
+
189
+ git__free(repo);
190
+ return NULL;
168
191
  }
169
192
 
170
193
  int git_repository_new(git_repository **out)
171
194
  {
172
- *out = repository_alloc();
195
+ git_repository *repo;
196
+
197
+ *out = repo = repository_alloc();
198
+ GITERR_CHECK_ALLOC(repo);
199
+
200
+ repo->is_bare = 1;
201
+
173
202
  return 0;
174
203
  }
175
204
 
@@ -189,7 +218,7 @@ static int load_config_data(git_repository *repo, const git_config *config)
189
218
  static int load_workdir(git_repository *repo, git_config *config, git_buf *parent_path)
190
219
  {
191
220
  int error;
192
- const git_config_entry *ce;
221
+ git_config_entry *ce;
193
222
  git_buf worktree = GIT_BUF_INIT;
194
223
 
195
224
  if (repo->is_bare)
@@ -202,7 +231,7 @@ static int load_workdir(git_repository *repo, git_config *config, git_buf *paren
202
231
  if (ce && ce->value) {
203
232
  if ((error = git_path_prettify_dir(
204
233
  &worktree, ce->value, repo->path_repository)) < 0)
205
- return error;
234
+ goto cleanup;
206
235
 
207
236
  repo->workdir = git_buf_detach(&worktree);
208
237
  }
@@ -210,14 +239,18 @@ static int load_workdir(git_repository *repo, git_config *config, git_buf *paren
210
239
  repo->workdir = git_buf_detach(parent_path);
211
240
  else {
212
241
  if (git_path_dirname_r(&worktree, repo->path_repository) < 0 ||
213
- git_path_to_dir(&worktree) < 0)
214
- return -1;
242
+ git_path_to_dir(&worktree) < 0) {
243
+ error = -1;
244
+ goto cleanup;
245
+ }
215
246
 
216
247
  repo->workdir = git_buf_detach(&worktree);
217
248
  }
218
249
 
219
250
  GITERR_CHECK_ALLOC(repo->workdir);
220
- return 0;
251
+ cleanup:
252
+ git_config_entry_free(ce);
253
+ return error;
221
254
  }
222
255
 
223
256
  /*
@@ -314,6 +347,7 @@ static int read_gitfile(git_buf *path_out, const char *file_path)
314
347
  static int find_repo(
315
348
  git_buf *repo_path,
316
349
  git_buf *parent_path,
350
+ git_buf *link_path,
317
351
  const char *start_path,
318
352
  uint32_t flags,
319
353
  const char *ceiling_dirs)
@@ -356,9 +390,14 @@ static int find_repo(
356
390
  git_buf repo_link = GIT_BUF_INIT;
357
391
 
358
392
  if (!(error = read_gitfile(&repo_link, path.ptr))) {
359
- if (valid_repository_path(&repo_link))
393
+ if (valid_repository_path(&repo_link)) {
360
394
  git_buf_swap(repo_path, &repo_link);
361
395
 
396
+ if (link_path)
397
+ error = git_buf_put(link_path,
398
+ path.ptr, path.size);
399
+ }
400
+
362
401
  git_buf_free(&repo_link);
363
402
  break;
364
403
  }
@@ -445,13 +484,16 @@ int git_repository_open_ext(
445
484
  const char *ceiling_dirs)
446
485
  {
447
486
  int error;
448
- git_buf path = GIT_BUF_INIT, parent = GIT_BUF_INIT;
487
+ git_buf path = GIT_BUF_INIT, parent = GIT_BUF_INIT,
488
+ link_path = GIT_BUF_INIT;
449
489
  git_repository *repo;
450
490
 
451
491
  if (repo_ptr)
452
492
  *repo_ptr = NULL;
453
493
 
454
- error = find_repo(&path, &parent, start_path, flags, ceiling_dirs);
494
+ error = find_repo(
495
+ &path, &parent, &link_path, start_path, flags, ceiling_dirs);
496
+
455
497
  if (error < 0 || !repo_ptr)
456
498
  return error;
457
499
 
@@ -461,6 +503,11 @@ int git_repository_open_ext(
461
503
  repo->path_repository = git_buf_detach(&path);
462
504
  GITERR_CHECK_ALLOC(repo->path_repository);
463
505
 
506
+ if (link_path.size) {
507
+ repo->path_gitlink = git_buf_detach(&link_path);
508
+ GITERR_CHECK_ALLOC(repo->path_gitlink);
509
+ }
510
+
464
511
  if ((flags & GIT_REPOSITORY_OPEN_BARE) != 0)
465
512
  repo->is_bare = 1;
466
513
  else {
@@ -512,7 +559,7 @@ int git_repository_discover(
512
559
 
513
560
  git_buf_sanitize(out);
514
561
 
515
- return find_repo(out, NULL, start_path, flags, ceiling_dirs);
562
+ return find_repo(out, NULL, NULL, start_path, flags, ceiling_dirs);
516
563
  }
517
564
 
518
565
  static int load_config(
@@ -776,7 +823,7 @@ int git_repository_index(git_index **out, git_repository *repo)
776
823
 
777
824
  void git_repository_set_index(git_repository *repo, git_index *index)
778
825
  {
779
- assert(repo && index);
826
+ assert(repo);
780
827
  set_index(repo, index);
781
828
  }
782
829
 
@@ -797,27 +844,88 @@ const char *git_repository_get_namespace(git_repository *repo)
797
844
  return repo->namespace;
798
845
  }
799
846
 
800
- const char *git_repository__8dot3_name(git_repository *repo)
847
+ #ifdef GIT_WIN32
848
+ static int reserved_names_add8dot3(git_repository *repo, const char *path)
801
849
  {
802
- if (!repo->has_8dot3) {
803
- repo->has_8dot3 = 1;
850
+ char *name = git_win32_path_8dot3_name(path);
851
+ const char *def = GIT_DIR_SHORTNAME;
852
+ size_t name_len, def_len = CONST_STRLEN(GIT_DIR_SHORTNAME);
853
+ git_buf *buf;
804
854
 
805
- #ifdef GIT_WIN32
855
+ if (!name)
856
+ return 0;
857
+
858
+ name_len = strlen(name);
859
+
860
+ if (name_len == def_len && memcmp(name, def, def_len) == 0) {
861
+ git__free(name);
862
+ return 0;
863
+ }
864
+
865
+ if ((buf = git_array_alloc(repo->reserved_names)) == NULL)
866
+ return -1;
867
+
868
+ git_buf_attach(buf, name, name_len);
869
+ return true;
870
+ }
871
+
872
+ bool git_repository__reserved_names(
873
+ git_buf **out, size_t *outlen, git_repository *repo, bool include_ntfs)
874
+ {
875
+ GIT_UNUSED(include_ntfs);
876
+
877
+ if (repo->reserved_names.size == 0) {
878
+ git_buf *buf;
879
+ size_t i;
880
+
881
+ /* Add the static defaults */
882
+ for (i = 0; i < git_repository__reserved_names_win32_len; i++) {
883
+ if ((buf = git_array_alloc(repo->reserved_names)) == NULL)
884
+ goto on_error;
885
+
886
+ buf->ptr = git_repository__reserved_names_win32[i].ptr;
887
+ buf->size = git_repository__reserved_names_win32[i].size;
888
+ }
889
+
890
+ /* Try to add any repo-specific reserved names */
806
891
  if (!repo->is_bare) {
807
- repo->name_8dot3 = git_win32_path_8dot3_name(repo->path_repository);
892
+ const char *reserved_path = repo->path_gitlink ?
893
+ repo->path_gitlink : repo->path_repository;
808
894
 
809
- /* We anticipate the 8.3 name is "GIT~1", so use a static for
810
- * easy testing in the common case */
811
- if (repo->name_8dot3 &&
812
- strcasecmp(repo->name_8dot3, git_repository__8dot3_default) == 0)
813
- repo->has_8dot3_default = 1;
895
+ if (reserved_names_add8dot3(repo, reserved_path) < 0)
896
+ goto on_error;
814
897
  }
815
- #endif
816
898
  }
817
899
 
818
- return repo->has_8dot3_default ?
819
- git_repository__8dot3_default : repo->name_8dot3;
900
+ *out = repo->reserved_names.ptr;
901
+ *outlen = repo->reserved_names.size;
902
+
903
+ return true;
904
+
905
+ /* Always give good defaults, even on OOM */
906
+ on_error:
907
+ *out = git_repository__reserved_names_win32;
908
+ *outlen = git_repository__reserved_names_win32_len;
909
+
910
+ return false;
911
+ }
912
+ #else
913
+ bool git_repository__reserved_names(
914
+ git_buf **out, size_t *outlen, git_repository *repo, bool include_ntfs)
915
+ {
916
+ GIT_UNUSED(repo);
917
+
918
+ if (include_ntfs) {
919
+ *out = git_repository__reserved_names_win32;
920
+ *outlen = git_repository__reserved_names_win32_len;
921
+ } else {
922
+ *out = git_repository__reserved_names_posix;
923
+ *outlen = git_repository__reserved_names_posix_len;
924
+ }
925
+
926
+ return true;
820
927
  }
928
+ #endif
821
929
 
822
930
  static int check_repositoryformatversion(git_config *config)
823
931
  {
@@ -1265,7 +1373,8 @@ static int repo_init_structure(
1265
1373
  if (opts->template_path)
1266
1374
  tdir = opts->template_path;
1267
1375
  else if ((error = git_config_open_default(&cfg)) >= 0) {
1268
- error = git_config_get_string(&tdir, cfg, "init.templatedir");
1376
+ if (!git_config_get_path(&template_buf, cfg, "init.templatedir"))
1377
+ tdir = template_buf.ptr;
1269
1378
  giterr_clear();
1270
1379
  }
1271
1380
 
@@ -1837,7 +1946,7 @@ int git_repository_hashfile(
1837
1946
  */
1838
1947
 
1839
1948
  error = git_path_join_unrooted(
1840
- &full_path, path, repo ? git_repository_workdir(repo) : NULL, NULL);
1949
+ &full_path, path, git_repository_workdir(repo), NULL);
1841
1950
  if (error < 0)
1842
1951
  return error;
1843
1952
 
@@ -1848,7 +1957,7 @@ int git_repository_hashfile(
1848
1957
  if (strlen(as_path) > 0) {
1849
1958
  error = git_filter_list_load(
1850
1959
  &fl, repo, NULL, as_path,
1851
- GIT_FILTER_TO_ODB, GIT_FILTER_OPT_DEFAULT);
1960
+ GIT_FILTER_TO_ODB, GIT_FILTER_DEFAULT);
1852
1961
  if (error < 0)
1853
1962
  return error;
1854
1963
  } else {
@@ -1886,98 +1995,149 @@ cleanup:
1886
1995
  return error;
1887
1996
  }
1888
1997
 
1889
- static bool looks_like_a_branch(const char *refname)
1998
+ static int checkout_message(git_buf *out, git_reference *old, const char *new)
1890
1999
  {
1891
- return git__prefixcmp(refname, GIT_REFS_HEADS_DIR) == 0;
2000
+ git_buf_puts(out, "checkout: moving from ");
2001
+
2002
+ if (git_reference_type(old) == GIT_REF_SYMBOLIC)
2003
+ git_buf_puts(out, git_reference__shorthand(git_reference_symbolic_target(old)));
2004
+ else
2005
+ git_buf_puts(out, git_oid_tostr_s(git_reference_target(old)));
2006
+
2007
+ git_buf_puts(out, " to ");
2008
+
2009
+ if (git_reference__is_branch(new))
2010
+ git_buf_puts(out, git_reference__shorthand(new));
2011
+ else
2012
+ git_buf_puts(out, new);
2013
+
2014
+ if (git_buf_oom(out))
2015
+ return -1;
2016
+
2017
+ return 0;
1892
2018
  }
1893
2019
 
1894
2020
  int git_repository_set_head(
1895
2021
  git_repository* repo,
1896
- const char* refname,
1897
- const git_signature *signature,
1898
- const char *log_message)
2022
+ const char* refname)
1899
2023
  {
1900
- git_reference *ref,
1901
- *new_head = NULL;
2024
+ git_reference *ref = NULL, *current = NULL, *new_head = NULL;
2025
+ git_buf log_message = GIT_BUF_INIT;
1902
2026
  int error;
1903
2027
 
1904
2028
  assert(repo && refname);
1905
2029
 
2030
+ if ((error = git_reference_lookup(&current, repo, GIT_HEAD_FILE)) < 0)
2031
+ return error;
2032
+
2033
+ if ((error = checkout_message(&log_message, current, refname)) < 0)
2034
+ goto cleanup;
2035
+
1906
2036
  error = git_reference_lookup(&ref, repo, refname);
1907
2037
  if (error < 0 && error != GIT_ENOTFOUND)
1908
- return error;
2038
+ goto cleanup;
1909
2039
 
1910
2040
  if (!error) {
1911
2041
  if (git_reference_is_branch(ref)) {
1912
2042
  error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE,
1913
- git_reference_name(ref), true, signature, log_message);
2043
+ git_reference_name(ref), true, git_buf_cstr(&log_message));
1914
2044
  } else {
1915
- error = git_repository_set_head_detached(repo, git_reference_target(ref),
1916
- signature, log_message);
2045
+ error = git_repository_set_head_detached(repo, git_reference_target(ref));
1917
2046
  }
1918
- } else if (looks_like_a_branch(refname)) {
2047
+ } else if (git_reference__is_branch(refname)) {
1919
2048
  error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE, refname,
1920
- true, signature, log_message);
2049
+ true, git_buf_cstr(&log_message));
1921
2050
  }
1922
2051
 
2052
+ cleanup:
2053
+ git_buf_free(&log_message);
2054
+ git_reference_free(current);
1923
2055
  git_reference_free(ref);
1924
2056
  git_reference_free(new_head);
1925
2057
  return error;
1926
2058
  }
1927
2059
 
1928
- int git_repository_set_head_detached(
1929
- git_repository* repo,
1930
- const git_oid* commitish,
1931
- const git_signature *signature,
1932
- const char *log_message)
2060
+ static int detach(git_repository *repo, const git_oid *id, const char *from)
1933
2061
  {
1934
2062
  int error;
1935
- git_object *object,
1936
- *peeled = NULL;
1937
- git_reference *new_head = NULL;
2063
+ git_buf log_message = GIT_BUF_INIT;
2064
+ git_object *object = NULL, *peeled = NULL;
2065
+ git_reference *new_head = NULL, *current = NULL;
1938
2066
 
1939
- assert(repo && commitish);
2067
+ assert(repo && id);
1940
2068
 
1941
- if ((error = git_object_lookup(&object, repo, commitish, GIT_OBJ_ANY)) < 0)
2069
+ if ((error = git_reference_lookup(&current, repo, GIT_HEAD_FILE)) < 0)
1942
2070
  return error;
1943
2071
 
2072
+ if ((error = git_object_lookup(&object, repo, id, GIT_OBJ_ANY)) < 0)
2073
+ goto cleanup;
2074
+
1944
2075
  if ((error = git_object_peel(&peeled, object, GIT_OBJ_COMMIT)) < 0)
1945
2076
  goto cleanup;
1946
2077
 
1947
- error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_object_id(peeled), true, signature, log_message);
2078
+ if (from == NULL)
2079
+ from = git_oid_tostr_s(git_object_id(peeled));
2080
+
2081
+ if ((error = checkout_message(&log_message, current, from)) < 0)
2082
+ goto cleanup;
2083
+
2084
+ error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_object_id(peeled), true, git_buf_cstr(&log_message));
1948
2085
 
1949
2086
  cleanup:
2087
+ git_buf_free(&log_message);
1950
2088
  git_object_free(object);
1951
2089
  git_object_free(peeled);
2090
+ git_reference_free(current);
1952
2091
  git_reference_free(new_head);
1953
2092
  return error;
1954
2093
  }
1955
2094
 
1956
- int git_repository_detach_head(
2095
+ int git_repository_set_head_detached(
1957
2096
  git_repository* repo,
1958
- const git_signature *signature,
1959
- const char *reflog_message)
2097
+ const git_oid* commitish)
2098
+ {
2099
+ return detach(repo, commitish, NULL);
2100
+ }
2101
+
2102
+ int git_repository_set_head_detached_from_annotated(
2103
+ git_repository *repo,
2104
+ const git_annotated_commit *commitish)
2105
+ {
2106
+ assert(repo && commitish);
2107
+
2108
+ return detach(repo, git_annotated_commit_id(commitish), commitish->ref_name);
2109
+ }
2110
+
2111
+ int git_repository_detach_head(git_repository* repo)
1960
2112
  {
1961
- git_reference *old_head = NULL,
1962
- *new_head = NULL;
2113
+ git_reference *old_head = NULL, *new_head = NULL, *current = NULL;
1963
2114
  git_object *object = NULL;
2115
+ git_buf log_message = GIT_BUF_INIT;
1964
2116
  int error;
1965
2117
 
1966
2118
  assert(repo);
1967
2119
 
1968
- if ((error = git_repository_head(&old_head, repo)) < 0)
2120
+ if ((error = git_reference_lookup(&current, repo, GIT_HEAD_FILE)) < 0)
1969
2121
  return error;
1970
2122
 
2123
+ if ((error = git_repository_head(&old_head, repo)) < 0)
2124
+ goto cleanup;
2125
+
1971
2126
  if ((error = git_object_lookup(&object, repo, git_reference_target(old_head), GIT_OBJ_COMMIT)) < 0)
1972
2127
  goto cleanup;
1973
2128
 
2129
+ if ((error = checkout_message(&log_message, current, git_oid_tostr_s(git_object_id(object)))) < 0)
2130
+ goto cleanup;
2131
+
1974
2132
  error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_reference_target(old_head),
1975
- 1, signature, reflog_message);
2133
+ 1, git_buf_cstr(&log_message));
1976
2134
 
1977
2135
  cleanup:
2136
+ git_buf_free(&log_message);
1978
2137
  git_object_free(object);
1979
2138
  git_reference_free(old_head);
1980
2139
  git_reference_free(new_head);
2140
+ git_reference_free(current);
1981
2141
  return error;
1982
2142
  }
1983
2143
 
@@ -2095,3 +2255,34 @@ int git_repository_init_init_options(
2095
2255
  GIT_REPOSITORY_INIT_OPTIONS_INIT);
2096
2256
  return 0;
2097
2257
  }
2258
+
2259
+ int git_repository_ident(const char **name, const char **email, const git_repository *repo)
2260
+ {
2261
+ *name = repo->ident_name;
2262
+ *email = repo->ident_email;
2263
+
2264
+ return 0;
2265
+ }
2266
+
2267
+ int git_repository_set_ident(git_repository *repo, const char *name, const char *email)
2268
+ {
2269
+ char *tmp_name = NULL, *tmp_email = NULL;
2270
+
2271
+ if (name) {
2272
+ tmp_name = git__strdup(name);
2273
+ GITERR_CHECK_ALLOC(tmp_name);
2274
+ }
2275
+
2276
+ if (email) {
2277
+ tmp_email = git__strdup(email);
2278
+ GITERR_CHECK_ALLOC(tmp_email);
2279
+ }
2280
+
2281
+ tmp_name = git__swap(repo->ident_name, tmp_name);
2282
+ tmp_email = git__swap(repo->ident_email, tmp_email);
2283
+
2284
+ git__free(tmp_name);
2285
+ git__free(tmp_email);
2286
+
2287
+ return 0;
2288
+ }