Michael Haggerty | 4cb7700 | 2015-11-10 12:42:36 +0100 | [diff] [blame] | 1 | #ifndef REFS_REFS_INTERNAL_H |
| 2 | #define REFS_REFS_INTERNAL_H |
| 3 | |
Ramsay Jones | 4eb4416 | 2018-09-19 01:12:47 +0100 | [diff] [blame] | 4 | #include "cache.h" |
| 5 | #include "refs.h" |
Junio C Hamano | 13f925f | 2018-07-09 14:36:12 -0700 | [diff] [blame] | 6 | #include "iterator.h" |
Beat Bolli | 91c2f20 | 2018-07-09 21:25:33 +0200 | [diff] [blame] | 7 | |
Ramsay Jones | 4eb4416 | 2018-09-19 01:12:47 +0100 | [diff] [blame] | 8 | struct ref_transaction; |
| 9 | |
Michael Haggerty | 4cb7700 | 2015-11-10 12:42:36 +0100 | [diff] [blame] | 10 | /* |
| 11 | * Data structures and functions for the internal use of the refs |
| 12 | * module. Code outside of the refs module should use only the public |
| 13 | * functions defined in "refs.h", and should *not* include this file. |
| 14 | */ |
| 15 | |
| 16 | /* |
Michael Haggerty | 5ac95fe | 2017-11-05 09:42:05 +0100 | [diff] [blame] | 17 | * The following flags can appear in `ref_update::flags`. Their |
Michael Haggerty | 91774af | 2017-11-05 09:42:06 +0100 | [diff] [blame] | 18 | * numerical values must not conflict with those of REF_NO_DEREF and |
Michael Haggerty | 5ac95fe | 2017-11-05 09:42:05 +0100 | [diff] [blame] | 19 | * REF_FORCE_CREATE_REFLOG, which are also stored in |
| 20 | * `ref_update::flags`. |
Michael Haggerty | 4cb7700 | 2015-11-10 12:42:36 +0100 | [diff] [blame] | 21 | */ |
| 22 | |
| 23 | /* |
Michael Haggerty | 78fb457 | 2017-11-05 09:42:09 +0100 | [diff] [blame] | 24 | * The reference should be updated to new_oid. |
David Turner | d99aa88 | 2016-02-24 17:58:50 -0500 | [diff] [blame] | 25 | */ |
Michael Haggerty | 5ac95fe | 2017-11-05 09:42:05 +0100 | [diff] [blame] | 26 | #define REF_HAVE_NEW (1 << 2) |
David Turner | d99aa88 | 2016-02-24 17:58:50 -0500 | [diff] [blame] | 27 | |
| 28 | /* |
Michael Haggerty | 5ac95fe | 2017-11-05 09:42:05 +0100 | [diff] [blame] | 29 | * The current reference's value should be checked to make sure that |
Michael Haggerty | 78fb457 | 2017-11-05 09:42:09 +0100 | [diff] [blame] | 30 | * it agrees with old_oid. |
Michael Haggerty | 92b1551 | 2016-04-25 15:56:07 +0200 | [diff] [blame] | 31 | */ |
Michael Haggerty | 5ac95fe | 2017-11-05 09:42:05 +0100 | [diff] [blame] | 32 | #define REF_HAVE_OLD (1 << 3) |
Michael Haggerty | 4463977 | 2017-01-06 17:22:43 +0100 | [diff] [blame] | 33 | |
| 34 | /* |
Michael Haggerty | 4ff0f01 | 2017-08-21 13:51:34 +0200 | [diff] [blame] | 35 | * Return the length of time to retry acquiring a loose reference lock |
| 36 | * before giving up, in milliseconds: |
| 37 | */ |
| 38 | long get_files_ref_lock_timeout_ms(void); |
| 39 | |
| 40 | /* |
Michael Haggerty | 4cb7700 | 2015-11-10 12:42:36 +0100 | [diff] [blame] | 41 | * Return true iff refname is minimally safe. "Safe" here means that |
| 42 | * deleting a loose reference by this name will not do any damage, for |
| 43 | * example by causing a file that is not a reference to be deleted. |
| 44 | * This function does not check that the reference name is legal; for |
| 45 | * that, use check_refname_format(). |
| 46 | * |
Michael Haggerty | 15ee2c7 | 2017-01-06 17:22:22 +0100 | [diff] [blame] | 47 | * A refname that starts with "refs/" is considered safe iff it |
| 48 | * doesn't contain any "." or ".." components or consecutive '/' |
| 49 | * characters, end with '/', or (on Windows) contain any '\' |
| 50 | * characters. Names that do not start with "refs/" are considered |
| 51 | * safe iff they consist entirely of upper case characters and '_' |
| 52 | * (like "HEAD" and "MERGE_HEAD" but not "config" or "FOO/BAR"). |
Michael Haggerty | 4cb7700 | 2015-11-10 12:42:36 +0100 | [diff] [blame] | 53 | */ |
| 54 | int refname_is_safe(const char *refname); |
| 55 | |
Michael Haggerty | 67be7c5 | 2017-06-23 09:01:37 +0200 | [diff] [blame] | 56 | /* |
| 57 | * Helper function: return true if refname, which has the specified |
| 58 | * oid and flags, can be resolved to an object in the database. If the |
| 59 | * referred-to object does not exist, emit a warning and return false. |
| 60 | */ |
| 61 | int ref_resolves_to_object(const char *refname, |
| 62 | const struct object_id *oid, |
| 63 | unsigned int flags); |
| 64 | |
Michael Haggerty | 4cb7700 | 2015-11-10 12:42:36 +0100 | [diff] [blame] | 65 | enum peel_status { |
| 66 | /* object was peeled successfully: */ |
| 67 | PEEL_PEELED = 0, |
| 68 | |
| 69 | /* |
| 70 | * object cannot be peeled because the named object (or an |
| 71 | * object referred to by a tag in the peel chain), does not |
| 72 | * exist. |
| 73 | */ |
| 74 | PEEL_INVALID = -1, |
| 75 | |
| 76 | /* object cannot be peeled because it is not a tag: */ |
| 77 | PEEL_NON_TAG = -2, |
| 78 | |
| 79 | /* ref_entry contains no peeled value because it is a symref: */ |
| 80 | PEEL_IS_SYMREF = -3, |
| 81 | |
| 82 | /* |
| 83 | * ref_entry cannot be peeled because it is broken (i.e., the |
| 84 | * symbolic reference cannot even be resolved to an object |
| 85 | * name): |
| 86 | */ |
| 87 | PEEL_BROKEN = -4 |
| 88 | }; |
| 89 | |
| 90 | /* |
| 91 | * Peel the named object; i.e., if the object is a tag, resolve the |
| 92 | * tag recursively until a non-tag is found. If successful, store the |
brian m. carlson | ac2ed0d | 2017-10-15 22:07:10 +0000 | [diff] [blame] | 93 | * result to oid and return PEEL_PEELED. If the object is not a tag |
Michael Haggerty | 4cb7700 | 2015-11-10 12:42:36 +0100 | [diff] [blame] | 94 | * or is not valid, return PEEL_NON_TAG or PEEL_INVALID, respectively, |
Michael Haggerty | 78fb457 | 2017-11-05 09:42:09 +0100 | [diff] [blame] | 95 | * and leave oid unchanged. |
Michael Haggerty | 4cb7700 | 2015-11-10 12:42:36 +0100 | [diff] [blame] | 96 | */ |
brian m. carlson | ac2ed0d | 2017-10-15 22:07:10 +0000 | [diff] [blame] | 97 | enum peel_status peel_object(const struct object_id *name, struct object_id *oid); |
Michael Haggerty | 4cb7700 | 2015-11-10 12:42:36 +0100 | [diff] [blame] | 98 | |
| 99 | /* |
Ben Peart | 80a6c20 | 2018-07-10 21:08:22 +0000 | [diff] [blame] | 100 | * Copy the reflog message msg to sb while cleaning up the whitespaces. |
| 101 | * Especially, convert LF to space, because reflog file is one line per entry. |
Michael Haggerty | 4cb7700 | 2015-11-10 12:42:36 +0100 | [diff] [blame] | 102 | */ |
Ben Peart | 80a6c20 | 2018-07-10 21:08:22 +0000 | [diff] [blame] | 103 | void copy_reflog_msg(struct strbuf *sb, const char *msg); |
Michael Haggerty | 4cb7700 | 2015-11-10 12:42:36 +0100 | [diff] [blame] | 104 | |
Michael Haggerty | 4cb7700 | 2015-11-10 12:42:36 +0100 | [diff] [blame] | 105 | /** |
Michael Haggerty | 78fb457 | 2017-11-05 09:42:09 +0100 | [diff] [blame] | 106 | * Information needed for a single ref update. Set new_oid to the new |
| 107 | * value or to null_oid to delete the ref. To check the old value |
| 108 | * while the ref is locked, set (flags & REF_HAVE_OLD) and set old_oid |
| 109 | * to the old value, or to null_oid to ensure the ref does not exist |
| 110 | * before update. |
Michael Haggerty | 4cb7700 | 2015-11-10 12:42:36 +0100 | [diff] [blame] | 111 | */ |
| 112 | struct ref_update { |
| 113 | /* |
Michael Haggerty | 5ac95fe | 2017-11-05 09:42:05 +0100 | [diff] [blame] | 114 | * If (flags & REF_HAVE_NEW), set the reference to this value |
| 115 | * (or delete it, if `new_oid` is `null_oid`). |
Michael Haggerty | 4cb7700 | 2015-11-10 12:42:36 +0100 | [diff] [blame] | 116 | */ |
brian m. carlson | 9849129 | 2017-05-06 22:10:23 +0000 | [diff] [blame] | 117 | struct object_id new_oid; |
Michael Haggerty | 6e30b2f | 2016-04-25 17:48:32 +0200 | [diff] [blame] | 118 | |
Michael Haggerty | 4cb7700 | 2015-11-10 12:42:36 +0100 | [diff] [blame] | 119 | /* |
| 120 | * If (flags & REF_HAVE_OLD), check that the reference |
Michael Haggerty | 5ac95fe | 2017-11-05 09:42:05 +0100 | [diff] [blame] | 121 | * previously had this value (or didn't previously exist, if |
| 122 | * `old_oid` is `null_oid`). |
Michael Haggerty | 4cb7700 | 2015-11-10 12:42:36 +0100 | [diff] [blame] | 123 | */ |
brian m. carlson | 9849129 | 2017-05-06 22:10:23 +0000 | [diff] [blame] | 124 | struct object_id old_oid; |
Michael Haggerty | 6e30b2f | 2016-04-25 17:48:32 +0200 | [diff] [blame] | 125 | |
Michael Haggerty | 4cb7700 | 2015-11-10 12:42:36 +0100 | [diff] [blame] | 126 | /* |
Michael Haggerty | 91774af | 2017-11-05 09:42:06 +0100 | [diff] [blame] | 127 | * One or more of REF_NO_DEREF, REF_FORCE_CREATE_REFLOG, |
Michael Haggerty | 5ac95fe | 2017-11-05 09:42:05 +0100 | [diff] [blame] | 128 | * REF_HAVE_NEW, REF_HAVE_OLD, or backend-specific flags. |
Michael Haggerty | 4cb7700 | 2015-11-10 12:42:36 +0100 | [diff] [blame] | 129 | */ |
| 130 | unsigned int flags; |
Michael Haggerty | 6e30b2f | 2016-04-25 17:48:32 +0200 | [diff] [blame] | 131 | |
David Turner | 7d61826 | 2016-09-04 18:08:43 +0200 | [diff] [blame] | 132 | void *backend_data; |
Michael Haggerty | 92b1551 | 2016-04-25 15:56:07 +0200 | [diff] [blame] | 133 | unsigned int type; |
Michael Haggerty | 4cb7700 | 2015-11-10 12:42:36 +0100 | [diff] [blame] | 134 | char *msg; |
Michael Haggerty | 6e30b2f | 2016-04-25 17:48:32 +0200 | [diff] [blame] | 135 | |
| 136 | /* |
| 137 | * If this ref_update was split off of a symref update via |
| 138 | * split_symref_update(), then this member points at that |
| 139 | * update. This is used for two purposes: |
| 140 | * 1. When reporting errors, we report the refname under which |
| 141 | * the update was originally requested. |
| 142 | * 2. When we read the old value of this reference, we |
| 143 | * propagate it back to its parent update for recording in |
| 144 | * the latter's reflog. |
| 145 | */ |
| 146 | struct ref_update *parent_update; |
| 147 | |
Michael Haggerty | 4cb7700 | 2015-11-10 12:42:36 +0100 | [diff] [blame] | 148 | const char refname[FLEX_ARRAY]; |
| 149 | }; |
| 150 | |
Michael Haggerty | 470be51 | 2017-03-20 17:33:07 +0100 | [diff] [blame] | 151 | int refs_read_raw_ref(struct ref_store *ref_store, |
brian m. carlson | 99afe91 | 2017-10-15 22:07:11 +0000 | [diff] [blame] | 152 | const char *refname, struct object_id *oid, |
Michael Haggerty | 470be51 | 2017-03-20 17:33:07 +0100 | [diff] [blame] | 153 | struct strbuf *referent, unsigned int *type); |
| 154 | |
Michael Haggerty | 4cb7700 | 2015-11-10 12:42:36 +0100 | [diff] [blame] | 155 | /* |
Michael Haggerty | 2ced105 | 2017-05-22 16:17:45 +0200 | [diff] [blame] | 156 | * Write an error to `err` and return a nonzero value iff the same |
| 157 | * refname appears multiple times in `refnames`. `refnames` must be |
| 158 | * sorted on entry to this function. |
| 159 | */ |
| 160 | int ref_update_reject_duplicates(struct string_list *refnames, |
| 161 | struct strbuf *err); |
| 162 | |
| 163 | /* |
Michael Haggerty | 7156451 | 2016-04-25 11:39:54 +0200 | [diff] [blame] | 164 | * Add a ref_update with the specified properties to transaction, and |
| 165 | * return a pointer to the new object. This function does not verify |
Michael Haggerty | 78fb457 | 2017-11-05 09:42:09 +0100 | [diff] [blame] | 166 | * that refname is well-formed. new_oid and old_oid are only |
Michael Haggerty | 7156451 | 2016-04-25 11:39:54 +0200 | [diff] [blame] | 167 | * dereferenced if the REF_HAVE_NEW and REF_HAVE_OLD bits, |
| 168 | * respectively, are set in flags. |
| 169 | */ |
| 170 | struct ref_update *ref_transaction_add_update( |
| 171 | struct ref_transaction *transaction, |
| 172 | const char *refname, unsigned int flags, |
brian m. carlson | 89f3bbd | 2017-10-15 22:06:53 +0000 | [diff] [blame] | 173 | const struct object_id *new_oid, |
| 174 | const struct object_id *old_oid, |
Michael Haggerty | 7156451 | 2016-04-25 11:39:54 +0200 | [diff] [blame] | 175 | const char *msg); |
| 176 | |
| 177 | /* |
Michael Haggerty | 4cb7700 | 2015-11-10 12:42:36 +0100 | [diff] [blame] | 178 | * Transaction states. |
Michael Haggerty | 30173b8 | 2017-05-22 16:17:44 +0200 | [diff] [blame] | 179 | * |
| 180 | * OPEN: The transaction is initialized and new updates can still be |
| 181 | * added to it. An OPEN transaction can be prepared, |
| 182 | * committed, freed, or aborted (freeing and aborting an open |
| 183 | * transaction are equivalent). |
| 184 | * |
| 185 | * PREPARED: ref_transaction_prepare(), which locks all of the |
| 186 | * references involved in the update and checks that the |
| 187 | * update has no errors, has been called successfully for the |
| 188 | * transaction. A PREPARED transaction can be committed or |
| 189 | * aborted. |
| 190 | * |
| 191 | * CLOSED: The transaction is no longer active. A transaction becomes |
| 192 | * CLOSED if there is a failure while building the transaction |
| 193 | * or if a transaction is committed or aborted. A CLOSED |
| 194 | * transaction can only be freed. |
Michael Haggerty | 4cb7700 | 2015-11-10 12:42:36 +0100 | [diff] [blame] | 195 | */ |
| 196 | enum ref_transaction_state { |
Michael Haggerty | 30173b8 | 2017-05-22 16:17:44 +0200 | [diff] [blame] | 197 | REF_TRANSACTION_OPEN = 0, |
| 198 | REF_TRANSACTION_PREPARED = 1, |
| 199 | REF_TRANSACTION_CLOSED = 2 |
Michael Haggerty | 4cb7700 | 2015-11-10 12:42:36 +0100 | [diff] [blame] | 200 | }; |
| 201 | |
| 202 | /* |
| 203 | * Data structure for holding a reference transaction, which can |
| 204 | * consist of checks and updates to multiple references, carried out |
| 205 | * as atomically as possible. This structure is opaque to callers. |
| 206 | */ |
| 207 | struct ref_transaction { |
Nguyễn Thái Ngọc Duy | c0fe4e8 | 2017-03-26 09:42:35 +0700 | [diff] [blame] | 208 | struct ref_store *ref_store; |
Michael Haggerty | 4cb7700 | 2015-11-10 12:42:36 +0100 | [diff] [blame] | 209 | struct ref_update **updates; |
| 210 | size_t alloc; |
| 211 | size_t nr; |
| 212 | enum ref_transaction_state state; |
Michael Haggerty | 3bf4f56 | 2017-09-08 15:51:44 +0200 | [diff] [blame] | 213 | void *backend_data; |
Michael Haggerty | 4cb7700 | 2015-11-10 12:42:36 +0100 | [diff] [blame] | 214 | }; |
| 215 | |
David Turner | 0845122 | 2015-11-10 12:42:40 +0100 | [diff] [blame] | 216 | /* |
| 217 | * Check for entries in extras that are within the specified |
| 218 | * directory, where dirname is a reference directory name including |
| 219 | * the trailing slash (e.g., "refs/heads/foo/"). Ignore any |
| 220 | * conflicting references that are found in skip. If there is a |
| 221 | * conflicting reference, return its name. |
| 222 | * |
| 223 | * extras and skip must be sorted lists of reference names. Either one |
| 224 | * can be NULL, signifying the empty list. |
| 225 | */ |
| 226 | const char *find_descendant_ref(const char *dirname, |
| 227 | const struct string_list *extras, |
| 228 | const struct string_list *skip); |
| 229 | |
David Turner | ff3a299 | 2016-09-04 18:08:08 +0200 | [diff] [blame] | 230 | /* |
| 231 | * Check whether an attempt to rename old_refname to new_refname would |
| 232 | * cause a D/F conflict with any existing reference (other than |
| 233 | * possibly old_refname). If there would be a conflict, emit an error |
| 234 | * message and return false; otherwise, return true. |
| 235 | * |
| 236 | * Note that this function is not safe against all races with other |
| 237 | * processes (though rename_ref() catches some races that might get by |
| 238 | * this check). |
| 239 | */ |
Nguyễn Thái Ngọc Duy | 7d2df05 | 2017-03-26 09:42:34 +0700 | [diff] [blame] | 240 | int refs_rename_ref_available(struct ref_store *refs, |
| 241 | const char *old_refname, |
| 242 | const char *new_refname); |
David Turner | 0845122 | 2015-11-10 12:42:40 +0100 | [diff] [blame] | 243 | |
David Turner | 2d0663b | 2016-04-07 15:03:10 -0400 | [diff] [blame] | 244 | /* We allow "recursive" symbolic refs. Only within reason, though */ |
| 245 | #define SYMREF_MAXDEPTH 5 |
David Turner | 9377059 | 2016-04-07 15:02:49 -0400 | [diff] [blame] | 246 | |
| 247 | /* Include broken references in a do_for_each_ref*() iteration: */ |
| 248 | #define DO_FOR_EACH_INCLUDE_BROKEN 0x01 |
| 249 | |
| 250 | /* |
Michael Haggerty | 3bc581b | 2016-06-18 06:15:15 +0200 | [diff] [blame] | 251 | * Reference iterators |
| 252 | * |
| 253 | * A reference iterator encapsulates the state of an in-progress |
| 254 | * iteration over references. Create an instance of `struct |
| 255 | * ref_iterator` via one of the functions in this module. |
| 256 | * |
| 257 | * A freshly-created ref_iterator doesn't yet point at a reference. To |
| 258 | * advance the iterator, call ref_iterator_advance(). If successful, |
| 259 | * this sets the iterator's refname, oid, and flags fields to describe |
| 260 | * the next reference and returns ITER_OK. The data pointed at by |
| 261 | * refname and oid belong to the iterator; if you want to retain them |
| 262 | * after calling ref_iterator_advance() again or calling |
| 263 | * ref_iterator_abort(), you must make a copy. When the iteration has |
| 264 | * been exhausted, ref_iterator_advance() releases any resources |
Elijah Newren | 15beaaa | 2019-11-05 17:07:23 +0000 | [diff] [blame] | 265 | * associated with the iteration, frees the ref_iterator object, and |
Michael Haggerty | 3bc581b | 2016-06-18 06:15:15 +0200 | [diff] [blame] | 266 | * returns ITER_DONE. If you want to abort the iteration early, call |
| 267 | * ref_iterator_abort(), which also frees the ref_iterator object and |
| 268 | * any associated resources. If there was an internal error advancing |
| 269 | * to the next entry, ref_iterator_advance() aborts the iteration, |
| 270 | * frees the ref_iterator, and returns ITER_ERROR. |
| 271 | * |
| 272 | * The reference currently being looked at can be peeled by calling |
| 273 | * ref_iterator_peel(). This function is often faster than peel_ref(), |
| 274 | * so it should be preferred when iterating over references. |
| 275 | * |
| 276 | * Putting it all together, a typical iteration looks like this: |
| 277 | * |
| 278 | * int ok; |
| 279 | * struct ref_iterator *iter = ...; |
| 280 | * |
| 281 | * while ((ok = ref_iterator_advance(iter)) == ITER_OK) { |
| 282 | * if (want_to_stop_iteration()) { |
| 283 | * ok = ref_iterator_abort(iter); |
| 284 | * break; |
| 285 | * } |
| 286 | * |
| 287 | * // Access information about the current reference: |
| 288 | * if (!(iter->flags & REF_ISSYMREF)) |
Tao Qingyun | 7b6057c | 2018-09-15 10:15:46 +0800 | [diff] [blame] | 289 | * printf("%s is %s\n", iter->refname, oid_to_hex(iter->oid)); |
Michael Haggerty | 3bc581b | 2016-06-18 06:15:15 +0200 | [diff] [blame] | 290 | * |
| 291 | * // If you need to peel the reference: |
| 292 | * ref_iterator_peel(iter, &oid); |
| 293 | * } |
| 294 | * |
| 295 | * if (ok != ITER_DONE) |
| 296 | * handle_error(); |
| 297 | */ |
| 298 | struct ref_iterator { |
| 299 | struct ref_iterator_vtable *vtable; |
Michael Haggerty | 8738a8a | 2017-09-13 19:15:55 +0200 | [diff] [blame] | 300 | |
| 301 | /* |
| 302 | * Does this `ref_iterator` iterate over references in order |
| 303 | * by refname? |
| 304 | */ |
| 305 | unsigned int ordered : 1; |
| 306 | |
Michael Haggerty | 3bc581b | 2016-06-18 06:15:15 +0200 | [diff] [blame] | 307 | const char *refname; |
| 308 | const struct object_id *oid; |
| 309 | unsigned int flags; |
| 310 | }; |
| 311 | |
| 312 | /* |
| 313 | * Advance the iterator to the first or next item and return ITER_OK. |
| 314 | * If the iteration is exhausted, free the resources associated with |
| 315 | * the ref_iterator and return ITER_DONE. On errors, free the iterator |
| 316 | * resources and return ITER_ERROR. It is a bug to use ref_iterator or |
| 317 | * call this function again after it has returned ITER_DONE or |
| 318 | * ITER_ERROR. |
| 319 | */ |
| 320 | int ref_iterator_advance(struct ref_iterator *ref_iterator); |
| 321 | |
| 322 | /* |
| 323 | * If possible, peel the reference currently being viewed by the |
| 324 | * iterator. Return 0 on success. |
| 325 | */ |
| 326 | int ref_iterator_peel(struct ref_iterator *ref_iterator, |
| 327 | struct object_id *peeled); |
| 328 | |
| 329 | /* |
| 330 | * End the iteration before it has been exhausted, freeing the |
| 331 | * reference iterator and any associated resources and returning |
| 332 | * ITER_DONE. If the abort itself failed, return ITER_ERROR. |
| 333 | */ |
| 334 | int ref_iterator_abort(struct ref_iterator *ref_iterator); |
| 335 | |
| 336 | /* |
| 337 | * An iterator over nothing (its first ref_iterator_advance() call |
| 338 | * returns ITER_DONE). |
| 339 | */ |
| 340 | struct ref_iterator *empty_ref_iterator_begin(void); |
| 341 | |
| 342 | /* |
| 343 | * Return true iff ref_iterator is an empty_ref_iterator. |
| 344 | */ |
| 345 | int is_empty_ref_iterator(struct ref_iterator *ref_iterator); |
| 346 | |
| 347 | /* |
Michael Haggerty | e121b9c | 2017-03-20 17:33:08 +0100 | [diff] [blame] | 348 | * Return an iterator that goes over each reference in `refs` for |
| 349 | * which the refname begins with prefix. If trim is non-zero, then |
| 350 | * trim that many characters off the beginning of each refname. flags |
| 351 | * can be DO_FOR_EACH_INCLUDE_BROKEN to include broken references in |
Michael Haggerty | 8738a8a | 2017-09-13 19:15:55 +0200 | [diff] [blame] | 352 | * the iteration. The output is ordered by refname. |
Michael Haggerty | e121b9c | 2017-03-20 17:33:08 +0100 | [diff] [blame] | 353 | */ |
| 354 | struct ref_iterator *refs_ref_iterator_begin( |
| 355 | struct ref_store *refs, |
| 356 | const char *prefix, int trim, int flags); |
| 357 | |
| 358 | /* |
Michael Haggerty | 3bc581b | 2016-06-18 06:15:15 +0200 | [diff] [blame] | 359 | * A callback function used to instruct merge_ref_iterator how to |
| 360 | * interleave the entries from iter0 and iter1. The function should |
| 361 | * return one of the constants defined in enum iterator_selection. It |
| 362 | * must not advance either of the iterators itself. |
| 363 | * |
| 364 | * The function must be prepared to handle the case that iter0 and/or |
| 365 | * iter1 is NULL, which indicates that the corresponding sub-iterator |
| 366 | * has been exhausted. Its return value must be consistent with the |
| 367 | * current states of the iterators; e.g., it must not return |
| 368 | * ITER_SKIP_1 if iter1 has already been exhausted. |
| 369 | */ |
| 370 | typedef enum iterator_selection ref_iterator_select_fn( |
| 371 | struct ref_iterator *iter0, struct ref_iterator *iter1, |
| 372 | void *cb_data); |
| 373 | |
| 374 | /* |
| 375 | * Iterate over the entries from iter0 and iter1, with the values |
| 376 | * interleaved as directed by the select function. The iterator takes |
| 377 | * ownership of iter0 and iter1 and frees them when the iteration is |
Michael Haggerty | 8738a8a | 2017-09-13 19:15:55 +0200 | [diff] [blame] | 378 | * over. A derived class should set `ordered` to 1 or 0 based on |
| 379 | * whether it generates its output in order by reference name. |
Michael Haggerty | 3bc581b | 2016-06-18 06:15:15 +0200 | [diff] [blame] | 380 | */ |
| 381 | struct ref_iterator *merge_ref_iterator_begin( |
Michael Haggerty | 8738a8a | 2017-09-13 19:15:55 +0200 | [diff] [blame] | 382 | int ordered, |
Michael Haggerty | 3bc581b | 2016-06-18 06:15:15 +0200 | [diff] [blame] | 383 | struct ref_iterator *iter0, struct ref_iterator *iter1, |
| 384 | ref_iterator_select_fn *select, void *cb_data); |
| 385 | |
| 386 | /* |
| 387 | * An iterator consisting of the union of the entries from front and |
| 388 | * back. If there are entries common to the two sub-iterators, use the |
| 389 | * one from front. Each iterator must iterate over its entries in |
| 390 | * strcmp() order by refname for this to work. |
| 391 | * |
| 392 | * The new iterator takes ownership of its arguments and frees them |
| 393 | * when the iteration is over. As a convenience to callers, if front |
| 394 | * or back is an empty_ref_iterator, then abort that one immediately |
| 395 | * and return the other iterator directly, without wrapping it. |
| 396 | */ |
| 397 | struct ref_iterator *overlay_ref_iterator_begin( |
| 398 | struct ref_iterator *front, struct ref_iterator *back); |
| 399 | |
| 400 | /* |
| 401 | * Wrap iter0, only letting through the references whose names start |
| 402 | * with prefix. If trim is set, set iter->refname to the name of the |
| 403 | * reference with that many characters trimmed off the front; |
| 404 | * otherwise set it to the full refname. The new iterator takes over |
| 405 | * ownership of iter0 and frees it when iteration is over. It makes |
| 406 | * its own copy of prefix. |
| 407 | * |
| 408 | * As an convenience to callers, if prefix is the empty string and |
| 409 | * trim is zero, this function returns iter0 directly, without |
| 410 | * wrapping it. |
Michael Haggerty | 8738a8a | 2017-09-13 19:15:55 +0200 | [diff] [blame] | 411 | * |
| 412 | * The resulting ref_iterator is ordered if iter0 is. |
Michael Haggerty | 3bc581b | 2016-06-18 06:15:15 +0200 | [diff] [blame] | 413 | */ |
| 414 | struct ref_iterator *prefix_ref_iterator_begin(struct ref_iterator *iter0, |
| 415 | const char *prefix, |
| 416 | int trim); |
| 417 | |
Michael Haggerty | 3bc581b | 2016-06-18 06:15:15 +0200 | [diff] [blame] | 418 | /* Internal implementation of reference iteration: */ |
| 419 | |
| 420 | /* |
| 421 | * Base class constructor for ref_iterators. Initialize the |
| 422 | * ref_iterator part of iter, setting its vtable pointer as specified. |
Michael Haggerty | 8738a8a | 2017-09-13 19:15:55 +0200 | [diff] [blame] | 423 | * `ordered` should be set to 1 if the iterator will iterate over |
| 424 | * references in order by refname; otherwise it should be set to 0. |
Michael Haggerty | 3bc581b | 2016-06-18 06:15:15 +0200 | [diff] [blame] | 425 | * This is meant to be called only by the initializers of derived |
| 426 | * classes. |
| 427 | */ |
| 428 | void base_ref_iterator_init(struct ref_iterator *iter, |
Michael Haggerty | 8738a8a | 2017-09-13 19:15:55 +0200 | [diff] [blame] | 429 | struct ref_iterator_vtable *vtable, |
| 430 | int ordered); |
Michael Haggerty | 3bc581b | 2016-06-18 06:15:15 +0200 | [diff] [blame] | 431 | |
| 432 | /* |
| 433 | * Base class destructor for ref_iterators. Destroy the ref_iterator |
| 434 | * part of iter and shallow-free the object. This is meant to be |
| 435 | * called only by the destructors of derived classes. |
| 436 | */ |
| 437 | void base_ref_iterator_free(struct ref_iterator *iter); |
| 438 | |
| 439 | /* Virtual function declarations for ref_iterators: */ |
| 440 | |
| 441 | typedef int ref_iterator_advance_fn(struct ref_iterator *ref_iterator); |
| 442 | |
| 443 | typedef int ref_iterator_peel_fn(struct ref_iterator *ref_iterator, |
| 444 | struct object_id *peeled); |
| 445 | |
| 446 | /* |
| 447 | * Implementations of this function should free any resources specific |
| 448 | * to the derived class, then call base_ref_iterator_free() to clean |
| 449 | * up and free the ref_iterator object. |
| 450 | */ |
| 451 | typedef int ref_iterator_abort_fn(struct ref_iterator *ref_iterator); |
| 452 | |
| 453 | struct ref_iterator_vtable { |
| 454 | ref_iterator_advance_fn *advance; |
| 455 | ref_iterator_peel_fn *peel; |
| 456 | ref_iterator_abort_fn *abort; |
| 457 | }; |
| 458 | |
| 459 | /* |
Michael Haggerty | 4c4de89 | 2016-06-18 06:15:16 +0200 | [diff] [blame] | 460 | * current_ref_iter is a performance hack: when iterating over |
| 461 | * references using the for_each_ref*() functions, current_ref_iter is |
| 462 | * set to the reference iterator before calling the callback function. |
| 463 | * If the callback function calls peel_ref(), then peel_ref() first |
| 464 | * checks whether the reference to be peeled is the one referred to by |
| 465 | * the iterator (it usually is) and if so, asks the iterator for the |
| 466 | * peeled version of the reference if it is available. This avoids a |
| 467 | * refname lookup in a common case. current_ref_iter is set to NULL |
| 468 | * when the iteration is over. |
David Turner | 9377059 | 2016-04-07 15:02:49 -0400 | [diff] [blame] | 469 | */ |
Michael Haggerty | 4c4de89 | 2016-06-18 06:15:16 +0200 | [diff] [blame] | 470 | extern struct ref_iterator *current_ref_iter; |
| 471 | |
| 472 | /* |
| 473 | * The common backend for the for_each_*ref* functions. Call fn for |
| 474 | * each reference in iter. If the iterator itself ever returns |
| 475 | * ITER_ERROR, return -1. If fn ever returns a non-zero value, stop |
| 476 | * the iteration and return that value. Otherwise, return 0. In any |
| 477 | * case, free the iterator when done. This function is basically an |
| 478 | * adapter between the callback style of reference iteration and the |
| 479 | * iterator style. |
| 480 | */ |
Stefan Beller | 4a6067c | 2018-08-20 18:24:16 +0000 | [diff] [blame] | 481 | int do_for_each_repo_ref_iterator(struct repository *r, |
| 482 | struct ref_iterator *iter, |
| 483 | each_repo_ref_fn fn, void *cb_data); |
David Turner | 2d0663b | 2016-04-07 15:03:10 -0400 | [diff] [blame] | 484 | |
David Turner | 0c09ec0 | 2016-09-04 18:08:44 +0200 | [diff] [blame] | 485 | /* |
| 486 | * Only include per-worktree refs in a do_for_each_ref*() iteration. |
| 487 | * Normally this will be used with a files ref_store, since that's |
| 488 | * where all reference backends will presumably store their |
| 489 | * per-worktree refs. |
| 490 | */ |
| 491 | #define DO_FOR_EACH_PER_WORKTREE_ONLY 0x02 |
Michael Haggerty | e1e33b7 | 2016-09-04 18:08:25 +0200 | [diff] [blame] | 492 | |
Michael Haggerty | 1a76900 | 2016-09-04 18:08:37 +0200 | [diff] [blame] | 493 | struct ref_store; |
| 494 | |
David Turner | 0c09ec0 | 2016-09-04 18:08:44 +0200 | [diff] [blame] | 495 | /* refs backends */ |
| 496 | |
Nguyễn Thái Ngọc Duy | 9e7ec63 | 2017-03-26 09:42:32 +0700 | [diff] [blame] | 497 | /* ref_store_init flags */ |
| 498 | #define REF_STORE_READ (1 << 0) |
| 499 | #define REF_STORE_WRITE (1 << 1) /* can perform update operations */ |
| 500 | #define REF_STORE_ODB (1 << 2) /* has access to object database */ |
| 501 | #define REF_STORE_MAIN (1 << 3) |
Nguyễn Thái Ngọc Duy | 0d8a814 | 2017-04-24 17:01:21 +0700 | [diff] [blame] | 502 | #define REF_STORE_ALL_CAPS (REF_STORE_READ | \ |
| 503 | REF_STORE_WRITE | \ |
| 504 | REF_STORE_ODB | \ |
| 505 | REF_STORE_MAIN) |
Nguyễn Thái Ngọc Duy | 9e7ec63 | 2017-03-26 09:42:32 +0700 | [diff] [blame] | 506 | |
Michael Haggerty | e1e33b7 | 2016-09-04 18:08:25 +0200 | [diff] [blame] | 507 | /* |
Nguyễn Thái Ngọc Duy | 5d0bc90 | 2017-03-26 09:42:31 +0700 | [diff] [blame] | 508 | * Initialize the ref_store for the specified gitdir. These functions |
| 509 | * should call base_ref_store_init() to initialize the shared part of |
| 510 | * the ref_store and to record the ref_store for later lookup. |
Michael Haggerty | e1e33b7 | 2016-09-04 18:08:25 +0200 | [diff] [blame] | 511 | */ |
Nguyễn Thái Ngọc Duy | 9e7ec63 | 2017-03-26 09:42:32 +0700 | [diff] [blame] | 512 | typedef struct ref_store *ref_store_init_fn(const char *gitdir, |
| 513 | unsigned int flags); |
Michael Haggerty | e1e33b7 | 2016-09-04 18:08:25 +0200 | [diff] [blame] | 514 | |
David Turner | 6fb5acf | 2016-09-04 18:08:41 +0200 | [diff] [blame] | 515 | typedef int ref_init_db_fn(struct ref_store *refs, struct strbuf *err); |
| 516 | |
Michael Haggerty | 30173b8 | 2017-05-22 16:17:44 +0200 | [diff] [blame] | 517 | typedef int ref_transaction_prepare_fn(struct ref_store *refs, |
| 518 | struct ref_transaction *transaction, |
| 519 | struct strbuf *err); |
| 520 | |
| 521 | typedef int ref_transaction_finish_fn(struct ref_store *refs, |
| 522 | struct ref_transaction *transaction, |
| 523 | struct strbuf *err); |
| 524 | |
| 525 | typedef int ref_transaction_abort_fn(struct ref_store *refs, |
| 526 | struct ref_transaction *transaction, |
| 527 | struct strbuf *err); |
| 528 | |
Michael Haggerty | e1e33b7 | 2016-09-04 18:08:25 +0200 | [diff] [blame] | 529 | typedef int ref_transaction_commit_fn(struct ref_store *refs, |
| 530 | struct ref_transaction *transaction, |
| 531 | struct strbuf *err); |
| 532 | |
Michael Haggerty | 8231527 | 2016-09-04 18:08:27 +0200 | [diff] [blame] | 533 | typedef int pack_refs_fn(struct ref_store *ref_store, unsigned int flags); |
Michael Haggerty | 284689b | 2016-09-04 18:08:28 +0200 | [diff] [blame] | 534 | typedef int create_symref_fn(struct ref_store *ref_store, |
| 535 | const char *ref_target, |
| 536 | const char *refs_heads_master, |
| 537 | const char *logmsg); |
Michael Haggerty | 64da419 | 2017-05-22 16:17:38 +0200 | [diff] [blame] | 538 | typedef int delete_refs_fn(struct ref_store *ref_store, const char *msg, |
David Turner | a27dcf8 | 2016-09-04 18:08:40 +0200 | [diff] [blame] | 539 | struct string_list *refnames, unsigned int flags); |
David Turner | 9b6b40d | 2016-09-04 18:08:42 +0200 | [diff] [blame] | 540 | typedef int rename_ref_fn(struct ref_store *ref_store, |
| 541 | const char *oldref, const char *newref, |
| 542 | const char *logmsg); |
Sahil Dua | 52d59cc | 2017-06-18 23:19:16 +0200 | [diff] [blame] | 543 | typedef int copy_ref_fn(struct ref_store *ref_store, |
| 544 | const char *oldref, const char *newref, |
| 545 | const char *logmsg); |
Michael Haggerty | 8231527 | 2016-09-04 18:08:27 +0200 | [diff] [blame] | 546 | |
Michael Haggerty | cf59644 | 2016-05-06 17:25:31 +0200 | [diff] [blame] | 547 | /* |
Michael Haggerty | e186057 | 2017-05-22 16:17:33 +0200 | [diff] [blame] | 548 | * Iterate over the references in `ref_store` whose names start with |
| 549 | * `prefix`. `prefix` is matched as a literal string, without regard |
| 550 | * for path separators. If prefix is NULL or the empty string, iterate |
Michael Haggerty | 8738a8a | 2017-09-13 19:15:55 +0200 | [diff] [blame] | 551 | * over all references in `ref_store`. The output is ordered by |
| 552 | * refname. |
Michael Haggerty | 1a76900 | 2016-09-04 18:08:37 +0200 | [diff] [blame] | 553 | */ |
| 554 | typedef struct ref_iterator *ref_iterator_begin_fn( |
| 555 | struct ref_store *ref_store, |
| 556 | const char *prefix, unsigned int flags); |
| 557 | |
David Turner | e3688bd | 2016-09-04 18:08:38 +0200 | [diff] [blame] | 558 | /* reflog functions */ |
| 559 | |
| 560 | /* |
| 561 | * Iterate over the references in the specified ref_store that have a |
| 562 | * reflog. The refs are iterated over in arbitrary order. |
| 563 | */ |
| 564 | typedef struct ref_iterator *reflog_iterator_begin_fn( |
| 565 | struct ref_store *ref_store); |
| 566 | |
| 567 | typedef int for_each_reflog_ent_fn(struct ref_store *ref_store, |
| 568 | const char *refname, |
| 569 | each_reflog_ent_fn fn, |
| 570 | void *cb_data); |
| 571 | typedef int for_each_reflog_ent_reverse_fn(struct ref_store *ref_store, |
| 572 | const char *refname, |
| 573 | each_reflog_ent_fn fn, |
| 574 | void *cb_data); |
| 575 | typedef int reflog_exists_fn(struct ref_store *ref_store, const char *refname); |
| 576 | typedef int create_reflog_fn(struct ref_store *ref_store, const char *refname, |
| 577 | int force_create, struct strbuf *err); |
| 578 | typedef int delete_reflog_fn(struct ref_store *ref_store, const char *refname); |
| 579 | typedef int reflog_expire_fn(struct ref_store *ref_store, |
brian m. carlson | 0155f71 | 2017-10-15 22:07:04 +0000 | [diff] [blame] | 580 | const char *refname, const struct object_id *oid, |
David Turner | e3688bd | 2016-09-04 18:08:38 +0200 | [diff] [blame] | 581 | unsigned int flags, |
| 582 | reflog_expiry_prepare_fn prepare_fn, |
| 583 | reflog_expiry_should_prune_fn should_prune_fn, |
| 584 | reflog_expiry_cleanup_fn cleanup_fn, |
| 585 | void *policy_cb_data); |
| 586 | |
Michael Haggerty | 1a76900 | 2016-09-04 18:08:37 +0200 | [diff] [blame] | 587 | /* |
Michael Haggerty | 34c7ad8 | 2016-09-04 18:08:20 +0200 | [diff] [blame] | 588 | * Read a reference from the specified reference store, non-recursively. |
| 589 | * Set type to describe the reference, and: |
Michael Haggerty | cf59644 | 2016-05-06 17:25:31 +0200 | [diff] [blame] | 590 | * |
brian m. carlson | 99afe91 | 2017-10-15 22:07:11 +0000 | [diff] [blame] | 591 | * - If refname is the name of a normal reference, fill in oid |
Michael Haggerty | cf59644 | 2016-05-06 17:25:31 +0200 | [diff] [blame] | 592 | * (leaving referent unchanged). |
| 593 | * |
| 594 | * - If refname is the name of a symbolic reference, write the full |
| 595 | * name of the reference to which it refers (e.g. |
| 596 | * "refs/heads/master") to referent and set the REF_ISSYMREF bit in |
brian m. carlson | 99afe91 | 2017-10-15 22:07:11 +0000 | [diff] [blame] | 597 | * type (leaving oid unchanged). The caller is responsible for |
Michael Haggerty | cf59644 | 2016-05-06 17:25:31 +0200 | [diff] [blame] | 598 | * validating that referent is a valid reference name. |
| 599 | * |
| 600 | * WARNING: refname might be used as part of a filename, so it is |
| 601 | * important from a security standpoint that it be safe in the sense |
| 602 | * of refname_is_safe(). Moreover, for symrefs this function sets |
| 603 | * referent to whatever the repository says, which might not be a |
| 604 | * properly-formatted or even safe reference name. NEITHER INPUT NOR |
| 605 | * OUTPUT REFERENCE NAMES ARE VALIDATED WITHIN THIS FUNCTION. |
| 606 | * |
| 607 | * Return 0 on success. If the ref doesn't exist, set errno to ENOENT |
| 608 | * and return -1. If the ref exists but is neither a symbolic ref nor |
brian m. carlson | 99afe91 | 2017-10-15 22:07:11 +0000 | [diff] [blame] | 609 | * an object ID, it is broken; set REF_ISBROKEN in type, set errno to |
Michael Haggerty | cf59644 | 2016-05-06 17:25:31 +0200 | [diff] [blame] | 610 | * EINVAL, and return -1. If there is another error reading the ref, |
| 611 | * set errno appropriately and return -1. |
| 612 | * |
| 613 | * Backend-specific flags might be set in type as well, regardless of |
| 614 | * outcome. |
| 615 | * |
| 616 | * It is OK for refname to point into referent. If so: |
| 617 | * |
| 618 | * - if the function succeeds with REF_ISSYMREF, referent will be |
| 619 | * overwritten and the memory formerly pointed to by it might be |
| 620 | * changed or even freed. |
| 621 | * |
| 622 | * - in all other cases, referent will be untouched, and therefore |
| 623 | * refname will still be valid and unchanged. |
| 624 | */ |
Michael Haggerty | e1e33b7 | 2016-09-04 18:08:25 +0200 | [diff] [blame] | 625 | typedef int read_raw_ref_fn(struct ref_store *ref_store, |
brian m. carlson | 99afe91 | 2017-10-15 22:07:11 +0000 | [diff] [blame] | 626 | const char *refname, struct object_id *oid, |
Michael Haggerty | e1e33b7 | 2016-09-04 18:08:25 +0200 | [diff] [blame] | 627 | struct strbuf *referent, unsigned int *type); |
Ronnie Sahlberg | 127b42a | 2016-09-04 18:08:16 +0200 | [diff] [blame] | 628 | |
Ronnie Sahlberg | 3dce444 | 2016-09-04 18:08:10 +0200 | [diff] [blame] | 629 | struct ref_storage_be { |
| 630 | struct ref_storage_be *next; |
| 631 | const char *name; |
Michael Haggerty | 00eebe3 | 2016-09-04 18:08:11 +0200 | [diff] [blame] | 632 | ref_store_init_fn *init; |
David Turner | 6fb5acf | 2016-09-04 18:08:41 +0200 | [diff] [blame] | 633 | ref_init_db_fn *init_db; |
Michael Haggerty | 30173b8 | 2017-05-22 16:17:44 +0200 | [diff] [blame] | 634 | |
| 635 | ref_transaction_prepare_fn *transaction_prepare; |
| 636 | ref_transaction_finish_fn *transaction_finish; |
| 637 | ref_transaction_abort_fn *transaction_abort; |
David Turner | fc68146 | 2016-09-04 18:08:39 +0200 | [diff] [blame] | 638 | ref_transaction_commit_fn *initial_transaction_commit; |
Michael Haggerty | e1e33b7 | 2016-09-04 18:08:25 +0200 | [diff] [blame] | 639 | |
Michael Haggerty | 8231527 | 2016-09-04 18:08:27 +0200 | [diff] [blame] | 640 | pack_refs_fn *pack_refs; |
Michael Haggerty | 284689b | 2016-09-04 18:08:28 +0200 | [diff] [blame] | 641 | create_symref_fn *create_symref; |
David Turner | a27dcf8 | 2016-09-04 18:08:40 +0200 | [diff] [blame] | 642 | delete_refs_fn *delete_refs; |
David Turner | 9b6b40d | 2016-09-04 18:08:42 +0200 | [diff] [blame] | 643 | rename_ref_fn *rename_ref; |
Sahil Dua | 52d59cc | 2017-06-18 23:19:16 +0200 | [diff] [blame] | 644 | copy_ref_fn *copy_ref; |
Michael Haggerty | 8231527 | 2016-09-04 18:08:27 +0200 | [diff] [blame] | 645 | |
Michael Haggerty | 1a76900 | 2016-09-04 18:08:37 +0200 | [diff] [blame] | 646 | ref_iterator_begin_fn *iterator_begin; |
Michael Haggerty | e1e33b7 | 2016-09-04 18:08:25 +0200 | [diff] [blame] | 647 | read_raw_ref_fn *read_raw_ref; |
David Turner | e3688bd | 2016-09-04 18:08:38 +0200 | [diff] [blame] | 648 | |
| 649 | reflog_iterator_begin_fn *reflog_iterator_begin; |
| 650 | for_each_reflog_ent_fn *for_each_reflog_ent; |
| 651 | for_each_reflog_ent_reverse_fn *for_each_reflog_ent_reverse; |
| 652 | reflog_exists_fn *reflog_exists; |
| 653 | create_reflog_fn *create_reflog; |
| 654 | delete_reflog_fn *delete_reflog; |
| 655 | reflog_expire_fn *reflog_expire; |
Ronnie Sahlberg | 3dce444 | 2016-09-04 18:08:10 +0200 | [diff] [blame] | 656 | }; |
| 657 | |
| 658 | extern struct ref_storage_be refs_be_files; |
Michael Haggerty | e0cc8ac | 2017-06-23 09:01:38 +0200 | [diff] [blame] | 659 | extern struct ref_storage_be refs_be_packed; |
Ronnie Sahlberg | 3dce444 | 2016-09-04 18:08:10 +0200 | [diff] [blame] | 660 | |
Michael Haggerty | 00eebe3 | 2016-09-04 18:08:11 +0200 | [diff] [blame] | 661 | /* |
| 662 | * A representation of the reference store for the main repository or |
| 663 | * a submodule. The ref_store instances for submodules are kept in a |
| 664 | * linked list. |
| 665 | */ |
| 666 | struct ref_store { |
| 667 | /* The backend describing this ref_store's storage scheme: */ |
| 668 | const struct ref_storage_be *be; |
Michael Haggerty | 00eebe3 | 2016-09-04 18:08:11 +0200 | [diff] [blame] | 669 | }; |
| 670 | |
| 671 | /* |
Michael Haggerty | fbfd0a2 | 2017-02-10 12:16:17 +0100 | [diff] [blame] | 672 | * Fill in the generic part of refs and add it to our collection of |
| 673 | * reference stores. |
Michael Haggerty | 00eebe3 | 2016-09-04 18:08:11 +0200 | [diff] [blame] | 674 | */ |
| 675 | void base_ref_store_init(struct ref_store *refs, |
Michael Haggerty | fbfd0a2 | 2017-02-10 12:16:17 +0100 | [diff] [blame] | 676 | const struct ref_storage_be *be); |
Michael Haggerty | 00eebe3 | 2016-09-04 18:08:11 +0200 | [diff] [blame] | 677 | |
Michael Haggerty | 4cb7700 | 2015-11-10 12:42:36 +0100 | [diff] [blame] | 678 | #endif /* REFS_REFS_INTERNAL_H */ |