rugged 0.26.0b3 → 0.26.0b4

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 (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;