rugged 0.26.0b3 → 0.26.0b4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -0
  3. data/ext/rugged/extconf.rb +10 -7
  4. data/ext/rugged/rugged.c +4 -6
  5. data/ext/rugged/rugged_repo.c +1 -1
  6. data/ext/rugged/rugged_revwalk.c +4 -4
  7. data/ext/rugged/rugged_tree.c +2 -2
  8. data/lib/rugged/version.rb +1 -1
  9. data/vendor/libgit2/CMakeLists.txt +13 -6
  10. data/vendor/libgit2/COPYING +33 -0
  11. data/vendor/libgit2/include/git2/branch.h +12 -0
  12. data/vendor/libgit2/include/git2/commit.h +6 -3
  13. data/vendor/libgit2/include/git2/common.h +11 -0
  14. data/vendor/libgit2/include/git2/errors.h +2 -0
  15. data/vendor/libgit2/include/git2/index.h +7 -6
  16. data/vendor/libgit2/include/git2/repository.h +91 -0
  17. data/vendor/libgit2/include/git2/stash.h +2 -2
  18. data/vendor/libgit2/include/git2/types.h +3 -0
  19. data/vendor/libgit2/include/git2/worktree.h +161 -0
  20. data/vendor/libgit2/src/attr.c +24 -16
  21. data/vendor/libgit2/src/attr_file.h +1 -1
  22. data/vendor/libgit2/src/attrcache.c +11 -10
  23. data/vendor/libgit2/src/attrcache.h +1 -4
  24. data/vendor/libgit2/src/blob.c +2 -2
  25. data/vendor/libgit2/src/branch.c +63 -0
  26. data/vendor/libgit2/src/buffer.h +2 -1
  27. data/vendor/libgit2/src/cache.c +21 -25
  28. data/vendor/libgit2/src/cache.h +1 -1
  29. data/vendor/libgit2/src/checkout.c +0 -2
  30. data/vendor/libgit2/src/cherrypick.c +2 -2
  31. data/vendor/libgit2/src/clone.c +2 -3
  32. data/vendor/libgit2/src/commit.c +8 -4
  33. data/vendor/libgit2/src/config_file.c +1 -3
  34. data/vendor/libgit2/src/describe.c +1 -3
  35. data/vendor/libgit2/src/diff_driver.c +2 -4
  36. data/vendor/libgit2/src/fetchhead.c +2 -2
  37. data/vendor/libgit2/src/fileops.c +1 -3
  38. data/vendor/libgit2/src/hash.h +5 -3
  39. data/vendor/libgit2/src/hash/hash_collisiondetect.h +57 -0
  40. data/vendor/libgit2/src/hash/sha1dc/sha1.c +1149 -0
  41. data/vendor/libgit2/src/hash/sha1dc/sha1.h +94 -0
  42. data/vendor/libgit2/src/hash/sha1dc/ubc_check.c +361 -0
  43. data/vendor/libgit2/src/hash/sha1dc/ubc_check.h +35 -0
  44. data/vendor/libgit2/src/idxmap.c +133 -0
  45. data/vendor/libgit2/src/idxmap.h +22 -60
  46. data/vendor/libgit2/src/ignore.c +7 -1
  47. data/vendor/libgit2/src/ignore.h +1 -1
  48. data/vendor/libgit2/src/index.c +11 -14
  49. data/vendor/libgit2/src/indexer.c +8 -11
  50. data/vendor/libgit2/src/merge.c +5 -5
  51. data/vendor/libgit2/src/mwindow.c +1 -3
  52. data/vendor/libgit2/src/odb.c +3 -3
  53. data/vendor/libgit2/src/odb.h +3 -0
  54. data/vendor/libgit2/src/odb_mempack.c +11 -18
  55. data/vendor/libgit2/src/offmap.c +83 -0
  56. data/vendor/libgit2/src/offmap.h +14 -34
  57. data/vendor/libgit2/src/oidmap.c +105 -0
  58. data/vendor/libgit2/src/oidmap.h +19 -22
  59. data/vendor/libgit2/src/pack-objects.c +10 -13
  60. data/vendor/libgit2/src/pack.c +17 -26
  61. data/vendor/libgit2/src/path.c +45 -24
  62. data/vendor/libgit2/src/rebase.c +3 -3
  63. data/vendor/libgit2/src/refdb_fs.c +81 -46
  64. data/vendor/libgit2/src/refs.c +13 -3
  65. data/vendor/libgit2/src/remote.c +6 -2
  66. data/vendor/libgit2/src/repository.c +318 -46
  67. data/vendor/libgit2/src/repository.h +5 -2
  68. data/vendor/libgit2/src/revert.c +2 -2
  69. data/vendor/libgit2/src/revwalk.c +6 -8
  70. data/vendor/libgit2/src/settings.c +5 -0
  71. data/vendor/libgit2/src/sortedcache.c +3 -5
  72. data/vendor/libgit2/src/strmap.c +95 -0
  73. data/vendor/libgit2/src/strmap.h +17 -37
  74. data/vendor/libgit2/src/submodule.c +12 -8
  75. data/vendor/libgit2/src/thread-utils.h +6 -0
  76. data/vendor/libgit2/src/transaction.c +5 -17
  77. data/vendor/libgit2/src/transports/local.c +2 -1
  78. data/vendor/libgit2/src/transports/smart.h +2 -0
  79. data/vendor/libgit2/src/transports/smart_protocol.c +3 -1
  80. data/vendor/libgit2/src/tree.c +2 -4
  81. data/vendor/libgit2/src/unix/posix.h +1 -1
  82. data/vendor/libgit2/src/worktree.c +432 -0
  83. data/vendor/libgit2/src/worktree.h +35 -0
  84. metadata +13 -2
@@ -173,7 +173,7 @@ GIT_EXTERN(int) git_stash_apply_init_options(
173
173
  * @param repo The owning repository.
174
174
  * @param index The position within the stash list. 0 points to the
175
175
  * most recent stashed state.
176
- * @param options Options to control how stashes are applied.
176
+ * @param options Optional options to control how stashes are applied.
177
177
  *
178
178
  * @return 0 on success, GIT_ENOTFOUND if there's no stashed state for the
179
179
  * given index, GIT_EMERGECONFLICT if changes exist in the working
@@ -242,7 +242,7 @@ GIT_EXTERN(int) git_stash_drop(
242
242
  * @param repo The owning repository.
243
243
  * @param index The position within the stash list. 0 points to the
244
244
  * most recent stashed state.
245
- * @param options Options to control how stashes are applied.
245
+ * @param options Optional options to control how stashes are applied.
246
246
  *
247
247
  * @return 0 on success, GIT_ENOTFOUND if there's no stashed state for the given
248
248
  * index, or error code. (see git_stash_apply() above for details)
@@ -104,6 +104,9 @@ typedef struct git_refdb_backend git_refdb_backend;
104
104
  */
105
105
  typedef struct git_repository git_repository;
106
106
 
107
+ /** Representation of a working tree */
108
+ typedef struct git_worktree git_worktree;
109
+
107
110
  /** Representation of a generic object in a repository */
108
111
  typedef struct git_object git_object;
109
112
 
@@ -0,0 +1,161 @@
1
+ /*
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
3
+ *
4
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
5
+ * a Linking Exception. For full terms see the included COPYING file.
6
+ */
7
+ #ifndef INCLUDE_git_worktree_h__
8
+ #define INCLUDE_git_worktree_h__
9
+
10
+ #include "common.h"
11
+ #include "buffer.h"
12
+ #include "types.h"
13
+ #include "strarray.h"
14
+
15
+ /**
16
+ * @file git2/worktrees.h
17
+ * @brief Git worktree related functions
18
+ * @defgroup git_commit Git worktree related functions
19
+ * @ingroup Git
20
+ * @{
21
+ */
22
+ GIT_BEGIN_DECL
23
+
24
+ /**
25
+ * List names of linked working trees
26
+ *
27
+ * The returned list should be released with `git_strarray_free`
28
+ * when no longer needed.
29
+ *
30
+ * @param out pointer to the array of working tree names
31
+ * @param repo the repo to use when listing working trees
32
+ * @return 0 or an error code
33
+ */
34
+ GIT_EXTERN(int) git_worktree_list(git_strarray *out, git_repository *repo);
35
+
36
+ /**
37
+ * Lookup a working tree by its name for a given repository
38
+ *
39
+ * @param out Output pointer to looked up worktree or `NULL`
40
+ * @param repo The repository containing worktrees
41
+ * @param name Name of the working tree to look up
42
+ * @return 0 or an error code
43
+ */
44
+ GIT_EXTERN(int) git_worktree_lookup(git_worktree **out, git_repository *repo, const char *name);
45
+
46
+ /**
47
+ * Free a previously allocated worktree
48
+ *
49
+ * @param wt worktree handle to close. If NULL nothing occurs.
50
+ */
51
+ GIT_EXTERN(void) git_worktree_free(git_worktree *wt);
52
+
53
+ /**
54
+ * Check if worktree is valid
55
+ *
56
+ * A valid worktree requires both the git data structures inside
57
+ * the linked parent repository and the linked working copy to be
58
+ * present.
59
+ *
60
+ * @param wt Worktree to check
61
+ * @return 0 when worktree is valid, error-code otherwise
62
+ */
63
+ GIT_EXTERN(int) git_worktree_validate(const git_worktree *wt);
64
+
65
+ /**
66
+ * Add a new working tree
67
+ *
68
+ * Add a new working tree for the repository, that is create the
69
+ * required data structures inside the repository and check out
70
+ * the current HEAD at `path`
71
+ *
72
+ * @param out Output pointer containing new working tree
73
+ * @param repo Repository to create working tree for
74
+ * @param name Name of the working tree
75
+ * @param path Path to create working tree at
76
+ * @return 0 or an error code
77
+ */
78
+ GIT_EXTERN(int) git_worktree_add(git_worktree **out, git_repository *repo, const char *name, const char *path);
79
+
80
+ /**
81
+ * Lock worktree if not already locked
82
+ *
83
+ * Lock a worktree, optionally specifying a reason why the linked
84
+ * working tree is being locked.
85
+ *
86
+ * @param wt Worktree to lock
87
+ * @param reason Reason why the working tree is being locked
88
+ * @return 0 on success, non-zero otherwise
89
+ */
90
+ GIT_EXTERN(int) git_worktree_lock(git_worktree *wt, char *reason);
91
+
92
+ /**
93
+ * Unlock a locked worktree
94
+ *
95
+ * @param wt Worktree to unlock
96
+ * @return 0 on success, 1 if worktree was not locked, error-code
97
+ * otherwise
98
+ */
99
+ GIT_EXTERN(int) git_worktree_unlock(git_worktree *wt);
100
+
101
+ /**
102
+ * Check if worktree is locked
103
+ *
104
+ * A worktree may be locked if the linked working tree is stored
105
+ * on a portable device which is not available.
106
+ *
107
+ * @param reason Buffer to store reason in. If NULL no reason is stored.
108
+ * @param wt Worktree to check
109
+ * @return 0 when the working tree not locked, a value greater
110
+ * than zero if it is locked, less than zero if there was an
111
+ * error
112
+ */
113
+ GIT_EXTERN(int) git_worktree_is_locked(git_buf *reason, const git_worktree *wt);
114
+
115
+ /**
116
+ * Flags which can be passed to git_worktree_prune to alter its
117
+ * behavior.
118
+ */
119
+ typedef enum {
120
+ /* Prune working tree even if working tree is valid */
121
+ GIT_WORKTREE_PRUNE_VALID = 1u << 0,
122
+ /* Prune working tree even if it is locked */
123
+ GIT_WORKTREE_PRUNE_LOCKED = 1u << 1,
124
+ /* Prune checked out working tree */
125
+ GIT_WORKTREE_PRUNE_WORKING_TREE = 1u << 2,
126
+ } git_worktree_prune_t;
127
+
128
+ /**
129
+ * Is the worktree prunable with the given set of flags?
130
+ *
131
+ * A worktree is not prunable in the following scenarios:
132
+ *
133
+ * - the worktree is linking to a valid on-disk worktree. The
134
+ * GIT_WORKTREE_PRUNE_VALID flag will cause this check to be
135
+ * ignored.
136
+ * - the worktree is not valid but locked. The
137
+ * GIT_WORKRTEE_PRUNE_LOCKED flag will cause this check to be
138
+ * ignored.
139
+ *
140
+ * If the worktree is not valid and not locked or if the above
141
+ * flags have been passed in, this function will return a
142
+ * positive value.
143
+ */
144
+ GIT_EXTERN(int) git_worktree_is_prunable(git_worktree *wt, unsigned flags);
145
+
146
+ /**
147
+ * Prune working tree
148
+ *
149
+ * Prune the working tree, that is remove the git data
150
+ * structures on disk. The repository will only be pruned of
151
+ * `git_worktree_is_prunable` succeeds.
152
+ *
153
+ * @param wt Worktree to prune
154
+ * @param flags git_worktree_prune_t flags
155
+ * @return 0 or an error code
156
+ */
157
+ GIT_EXTERN(int) git_worktree_prune(git_worktree *wt, unsigned flags);
158
+
159
+ /** @} */
160
+ GIT_END_DECL
161
+ #endif
@@ -7,8 +7,6 @@
7
7
  #include "git2/oid.h"
8
8
  #include <ctype.h>
9
9
 
10
- GIT__USE_STRMAP
11
-
12
10
  const char *git_attr__true = "[internal]__TRUE__";
13
11
  const char *git_attr__false = "[internal]__FALSE__";
14
12
  const char *git_attr__unset = "[internal]__UNSET__";
@@ -209,7 +207,7 @@ int git_attr_foreach(
209
207
  if (git_strmap_exists(seen, assign->name))
210
208
  continue;
211
209
 
212
- git_strmap_insert(seen, assign->name, assign, error);
210
+ git_strmap_insert(seen, assign->name, assign, &error);
213
211
  if (error < 0)
214
212
  goto cleanup;
215
213
 
@@ -292,7 +290,7 @@ static int attr_setup(git_repository *repo, git_attr_session *attr_session)
292
290
  int error = 0;
293
291
  const char *workdir = git_repository_workdir(repo);
294
292
  git_index *idx = NULL;
295
- git_buf sys = GIT_BUF_INIT;
293
+ git_buf path = GIT_BUF_INIT;
296
294
 
297
295
  if (attr_session && attr_session->init_setup)
298
296
  return 0;
@@ -304,40 +302,45 @@ static int attr_setup(git_repository *repo, git_attr_session *attr_session)
304
302
  * definitions will be available for later file parsing
305
303
  */
306
304
 
307
- error = system_attr_file(&sys, attr_session);
305
+ error = system_attr_file(&path, attr_session);
308
306
 
309
307
  if (error == 0)
310
308
  error = preload_attr_file(
311
- repo, attr_session, GIT_ATTR_FILE__FROM_FILE, NULL, sys.ptr);
309
+ repo, attr_session, GIT_ATTR_FILE__FROM_FILE, NULL, path.ptr);
312
310
 
313
311
  if (error != GIT_ENOTFOUND)
314
- return error;
315
-
316
- git_buf_free(&sys);
312
+ goto out;
317
313
 
318
314
  if ((error = preload_attr_file(
319
315
  repo, attr_session, GIT_ATTR_FILE__FROM_FILE,
320
316
  NULL, git_repository_attr_cache(repo)->cfg_attr_file)) < 0)
321
- return error;
317
+ goto out;
318
+
319
+ if ((error = git_repository_item_path(&path,
320
+ repo, GIT_REPOSITORY_ITEM_INFO)) < 0)
321
+ goto out;
322
322
 
323
323
  if ((error = preload_attr_file(
324
324
  repo, attr_session, GIT_ATTR_FILE__FROM_FILE,
325
- git_repository_path(repo), GIT_ATTR_FILE_INREPO)) < 0)
326
- return error;
325
+ path.ptr, GIT_ATTR_FILE_INREPO)) < 0)
326
+ goto out;
327
327
 
328
328
  if (workdir != NULL &&
329
329
  (error = preload_attr_file(
330
330
  repo, attr_session, GIT_ATTR_FILE__FROM_FILE, workdir, GIT_ATTR_FILE)) < 0)
331
- return error;
331
+ goto out;
332
332
 
333
333
  if ((error = git_repository_index__weakptr(&idx, repo)) < 0 ||
334
334
  (error = preload_attr_file(
335
335
  repo, attr_session, GIT_ATTR_FILE__FROM_INDEX, NULL, GIT_ATTR_FILE)) < 0)
336
- return error;
336
+ goto out;
337
337
 
338
338
  if (attr_session)
339
339
  attr_session->init_setup = 1;
340
340
 
341
+ out:
342
+ git_buf_free(&path);
343
+
341
344
  return error;
342
345
  }
343
346
 
@@ -472,7 +475,7 @@ static int collect_attr_files(
472
475
  git_vector *files)
473
476
  {
474
477
  int error = 0;
475
- git_buf dir = GIT_BUF_INIT;
478
+ git_buf dir = GIT_BUF_INIT, attrfile = GIT_BUF_INIT;
476
479
  const char *workdir = git_repository_workdir(repo);
477
480
  attr_walk_up_info info = { NULL };
478
481
 
@@ -494,9 +497,13 @@ static int collect_attr_files(
494
497
  * - $GIT_PREFIX/etc/gitattributes
495
498
  */
496
499
 
500
+ error = git_repository_item_path(&attrfile, repo, GIT_REPOSITORY_ITEM_INFO);
501
+ if (error < 0)
502
+ goto cleanup;
503
+
497
504
  error = push_attr_file(
498
505
  repo, attr_session, files, GIT_ATTR_FILE__FROM_FILE,
499
- git_repository_path(repo), GIT_ATTR_FILE_INREPO);
506
+ attrfile.ptr, GIT_ATTR_FILE_INREPO);
500
507
  if (error < 0)
501
508
  goto cleanup;
502
509
 
@@ -538,6 +545,7 @@ static int collect_attr_files(
538
545
  cleanup:
539
546
  if (error < 0)
540
547
  release_attr_files(files);
548
+ git_buf_free(&attrfile);
541
549
  git_buf_free(&dir);
542
550
 
543
551
  return error;
@@ -15,7 +15,7 @@
15
15
  #include "fileops.h"
16
16
 
17
17
  #define GIT_ATTR_FILE ".gitattributes"
18
- #define GIT_ATTR_FILE_INREPO "info/attributes"
18
+ #define GIT_ATTR_FILE_INREPO "attributes"
19
19
  #define GIT_ATTR_FILE_SYSTEM "gitattributes"
20
20
  #define GIT_ATTR_FILE_XDG "attributes"
21
21
 
@@ -5,8 +5,6 @@
5
5
  #include "sysdir.h"
6
6
  #include "ignore.h"
7
7
 
8
- GIT__USE_STRMAP
9
-
10
8
  GIT_INLINE(int) attr_cache_lock(git_attr_cache *cache)
11
9
  {
12
10
  GIT_UNUSED(cache); /* avoid warning if threading is off */
@@ -82,7 +80,7 @@ static int attr_cache_make_entry(
82
80
  &entry, git_repository_workdir(repo), path, &cache->pool);
83
81
 
84
82
  if (!error) {
85
- git_strmap_insert(cache->files, entry->path, entry, error);
83
+ git_strmap_insert(cache->files, entry->path, entry, &error);
86
84
  if (error > 0)
87
85
  error = 0;
88
86
  }
@@ -105,8 +103,11 @@ static int attr_cache_upsert(git_attr_cache *cache, git_attr_file *file)
105
103
  GIT_REFCOUNT_OWN(file, entry);
106
104
  GIT_REFCOUNT_INC(file);
107
105
 
108
- old = git__compare_and_swap(
109
- &entry->file[file->source], entry->file[file->source], file);
106
+ /*
107
+ * Replace the existing value if another thread has
108
+ * created it in the meantime.
109
+ */
110
+ old = git__swap(entry->file[file->source], file);
110
111
 
111
112
  if (old) {
112
113
  GIT_REFCOUNT_OWN(old, NULL);
@@ -311,7 +312,7 @@ static void attr_cache__free(git_attr_cache *cache)
311
312
  if (!cache)
312
313
  return;
313
314
 
314
- unlock = (git_mutex_lock(&cache->lock) == 0);
315
+ unlock = (attr_cache_lock(cache) == 0);
315
316
 
316
317
  if (cache->files != NULL) {
317
318
  git_attr_file_entry *entry;
@@ -347,13 +348,13 @@ static void attr_cache__free(git_attr_cache *cache)
347
348
  cache->cfg_excl_file = NULL;
348
349
 
349
350
  if (unlock)
350
- git_mutex_unlock(&cache->lock);
351
+ attr_cache_unlock(cache);
351
352
  git_mutex_free(&cache->lock);
352
353
 
353
354
  git__free(cache);
354
355
  }
355
356
 
356
- int git_attr_cache__do_init(git_repository *repo)
357
+ int git_attr_cache__init(git_repository *repo)
357
358
  {
358
359
  int ret = 0;
359
360
  git_attr_cache *cache = git_repository_attr_cache(repo);
@@ -431,11 +432,11 @@ int git_attr_cache__insert_macro(git_repository *repo, git_attr_rule *macro)
431
432
  if (macro->assigns.length == 0)
432
433
  return 0;
433
434
 
434
- if (git_mutex_lock(&cache->lock) < 0) {
435
+ if (attr_cache_lock(cache) < 0) {
435
436
  giterr_set(GITERR_OS, "unable to get attr cache lock");
436
437
  error = -1;
437
438
  } else {
438
- git_strmap_insert(macros, macro->match.pattern, macro, error);
439
+ git_strmap_insert(macros, macro->match.pattern, macro, &error);
439
440
  git_mutex_unlock(&cache->lock);
440
441
  }
441
442
 
@@ -22,10 +22,7 @@ typedef struct {
22
22
  git_pool pool;
23
23
  } git_attr_cache;
24
24
 
25
- extern int git_attr_cache__do_init(git_repository *repo);
26
-
27
- #define git_attr_cache__init(REPO) \
28
- (git_repository_attr_cache(REPO) ? 0 : git_attr_cache__do_init(REPO))
25
+ extern int git_attr_cache__init(git_repository *repo);
29
26
 
30
27
  /* get file - loading and reload as needed */
31
28
  extern int git_attr_cache__get(
@@ -326,8 +326,8 @@ int git_blob_create_fromstream(git_writestream **out, git_repository *repo, cons
326
326
  stream->parent.close = blob_writestream_close;
327
327
  stream->parent.free = blob_writestream_free;
328
328
 
329
- if ((error = git_buf_joinpath(&path,
330
- git_repository_path(repo), GIT_OBJECTS_DIR "streamed")) < 0)
329
+ if ((error = git_repository_item_path(&path, repo, GIT_REPOSITORY_ITEM_OBJECTS)) < 0
330
+ || (error = git_buf_joinpath(&path, path.ptr, "streamed")) < 0)
331
331
  goto cleanup;
332
332
 
333
333
  if ((error = git_filebuf_open_withsize(&stream->fbuf, git_buf_cstr(&path), GIT_FILEBUF_TEMPORARY,
@@ -13,6 +13,7 @@
13
13
  #include "refs.h"
14
14
  #include "remote.h"
15
15
  #include "annotated_commit.h"
16
+ #include "worktree.h"
16
17
 
17
18
  #include "git2/branch.h"
18
19
 
@@ -126,6 +127,62 @@ int git_branch_create_from_annotated(
126
127
  repository, branch_name, commit->commit, commit->description, force);
127
128
  }
128
129
 
130
+ int git_branch_is_checked_out(
131
+ const git_reference *branch)
132
+ {
133
+ git_buf path = GIT_BUF_INIT, buf = GIT_BUF_INIT;
134
+ git_strarray worktrees;
135
+ git_reference *ref = NULL;
136
+ git_repository *repo;
137
+ const char *worktree;
138
+ int found = false;
139
+ size_t i;
140
+
141
+ assert(branch && git_reference_is_branch(branch));
142
+
143
+ repo = git_reference_owner(branch);
144
+
145
+ if (git_worktree_list(&worktrees, repo) < 0)
146
+ return -1;
147
+
148
+ for (i = 0; i < worktrees.count; i++) {
149
+ worktree = worktrees.strings[i];
150
+
151
+ if (git_repository_head_for_worktree(&ref, repo, worktree) < 0)
152
+ continue;
153
+
154
+ if (git__strcmp(ref->name, branch->name) == 0) {
155
+ found = true;
156
+ git_reference_free(ref);
157
+ break;
158
+ }
159
+
160
+ git_reference_free(ref);
161
+ }
162
+ git_strarray_free(&worktrees);
163
+
164
+ if (found)
165
+ return found;
166
+
167
+ /* Check HEAD of parent */
168
+ if (git_buf_joinpath(&path, repo->commondir, GIT_HEAD_FILE) < 0)
169
+ goto out;
170
+ if (git_futils_readbuffer(&buf, path.ptr) < 0)
171
+ goto out;
172
+ if (git__prefixcmp(buf.ptr, "ref: ") == 0)
173
+ git_buf_consume(&buf, buf.ptr + strlen("ref: "));
174
+ git_buf_rtrim(&buf);
175
+
176
+ found = git__strcmp(buf.ptr, branch->name) == 0;
177
+
178
+ out:
179
+ git_buf_free(&buf);
180
+ git_buf_free(&path);
181
+
182
+ return found;
183
+ }
184
+
185
+
129
186
  int git_branch_delete(git_reference *branch)
130
187
  {
131
188
  int is_head;
@@ -149,6 +206,12 @@ int git_branch_delete(git_reference *branch)
149
206
  return -1;
150
207
  }
151
208
 
209
+ if (git_reference_is_branch(branch) && git_branch_is_checked_out(branch)) {
210
+ giterr_set(GITERR_REFERENCE, "Cannot delete branch '%s' as it is "
211
+ "the current HEAD of a linked repository.", git_reference_name(branch));
212
+ return -1;
213
+ }
214
+
152
215
  if (git_buf_join(&config_section, '.', "branch",
153
216
  git_reference_name(branch) + strlen(GIT_REFS_HEADS_DIR)) < 0)
154
217
  goto on_error;