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_submodule_h__
8 #define INCLUDE_submodule_h__
9 
10 #include "common.h"
11 
12 #include "git2/submodule.h"
13 #include "git2/repository.h"
14 #include "futils.h"
15 
16 /* Notes:
17  *
18  * Submodule information can be in four places: the index, the config files
19  * (both .git/config and .gitmodules), the HEAD tree, and the working
20  * directory.
21  *
22  * In the index:
23  * - submodule is found by path
24  * - may be missing, present, or of the wrong type
25  * - will have an oid if present
26  *
27  * In the HEAD tree:
28  * - submodule is found by path
29  * - may be missing, present, or of the wrong type
30  * - will have an oid if present
31  *
32  * In the config files:
33  * - submodule is found by submodule "name" which is usually the path
34  * - may be missing or present
35  * - will have a name, path, url, and other properties
36  *
37  * In the working directory:
38  * - submodule is found by path
39  * - may be missing, an empty directory, a checked out directory,
40  *   or of the wrong type
41  * - if checked out, will have a HEAD oid
42  * - if checked out, will have git history that can be used to compare oids
43  * - if checked out, may have modified files and/or untracked files
44  */
45 
46 /**
47  * Description of submodule
48  *
49  * This record describes a submodule found in a repository.  There should be
50  * an entry for every submodule found in the HEAD and index, and for every
51  * submodule described in .gitmodules.  The fields are as follows:
52  *
53  * - `rc` tracks the refcount of how many hash table entries in the
54  *   git_submodule_cache there are for this submodule.  It only comes into
55  *   play if the name and path of the submodule differ.
56  *
57  * - `name` is the name of the submodule from .gitmodules.
58  * - `path` is the path to the submodule from the repo root.  It is almost
59  *    always the same as `name`.
60  * - `url` is the url for the submodule.
61  * - `update` is a git_submodule_update_t value - see gitmodules(5) update.
62  * - `update_default` is the update value from the config
63  * - `ignore` is a git_submodule_ignore_t value - see gitmodules(5) ignore.
64  * - `ignore_default` is the ignore value from the config
65  * - `fetch_recurse` is a git_submodule_recurse_t value - see gitmodules(5)
66  *    fetchRecurseSubmodules.
67  * - `fetch_recurse_default` is the recurse value from the config
68  *
69  * - `repo` is the parent repository that contains this submodule.
70  * - `flags` after for internal use, tracking where this submodule has been
71  *   found (head, index, config, workdir) and known status info, etc.
72  * - `head_oid` is the SHA1 for the submodule path in the repo HEAD.
73  * - `index_oid` is the SHA1 for the submodule recorded in the index.
74  * - `wd_oid` is the SHA1 for the HEAD of the checked out submodule.
75  *
76  * If the submodule has been added to .gitmodules but not yet git added,
77  * then the `index_oid` will be zero but still marked valid.  If the
78  * submodule has been deleted, but the delete has not been committed yet,
79  * then the `index_oid` will be set, but the `url` will be NULL.
80  */
81 struct git_submodule {
82 	git_refcount rc;
83 
84 	/* information from config */
85 	char *name;
86 	char *path; /* important: may just point to "name" string */
87 	char *url;
88 	char *branch;
89 	git_submodule_update_t update;
90 	git_submodule_update_t update_default;
91 	git_submodule_ignore_t ignore;
92 	git_submodule_ignore_t ignore_default;
93 	git_submodule_recurse_t fetch_recurse;
94 	git_submodule_recurse_t fetch_recurse_default;
95 
96 	/* internal information */
97 	git_repository *repo;
98 	uint32_t flags;
99 	git_oid head_oid;
100 	git_oid index_oid;
101 	git_oid wd_oid;
102 };
103 
104 /* Force revalidation of submodule data cache (alloc as needed) */
105 extern int git_submodule_cache_refresh(git_repository *repo);
106 
107 /* Release all submodules */
108 extern void git_submodule_cache_free(git_repository *repo);
109 
110 /* Additional flags on top of public GIT_SUBMODULE_STATUS values */
111 enum {
112 	GIT_SUBMODULE_STATUS__WD_SCANNED          = (1u << 20),
113 	GIT_SUBMODULE_STATUS__HEAD_OID_VALID      = (1u << 21),
114 	GIT_SUBMODULE_STATUS__INDEX_OID_VALID     = (1u << 22),
115 	GIT_SUBMODULE_STATUS__WD_OID_VALID        = (1u << 23),
116 	GIT_SUBMODULE_STATUS__HEAD_NOT_SUBMODULE  = (1u << 24),
117 	GIT_SUBMODULE_STATUS__INDEX_NOT_SUBMODULE = (1u << 25),
118 	GIT_SUBMODULE_STATUS__WD_NOT_SUBMODULE    = (1u << 26),
119 	GIT_SUBMODULE_STATUS__INDEX_MULTIPLE_ENTRIES = (1u << 27),
120 };
121 
122 #define GIT_SUBMODULE_STATUS__CLEAR_INTERNAL(S) \
123 	((S) & ~(0xFFFFFFFFu << 20))
124 
125 /* Internal lookup does not attempt to refresh cached data */
126 extern int git_submodule__lookup(
127 	git_submodule **out, git_repository *repo, const char *path);
128 
129 /* Internal status fn returns status and optionally the various OIDs */
130 extern int git_submodule__status(
131 	unsigned int *out_status,
132 	git_oid *out_head_id,
133 	git_oid *out_index_id,
134 	git_oid *out_wd_id,
135 	git_submodule *sm,
136 	git_submodule_ignore_t ign);
137 
138 /* Open submodule repository as bare repo for quick HEAD check, etc. */
139 extern int git_submodule_open_bare(
140 	git_repository **repo,
141 	git_submodule *submodule);
142 
143 extern int git_submodule_parse_ignore(
144 	git_submodule_ignore_t *out, const char *value);
145 extern int git_submodule_parse_update(
146 	git_submodule_update_t *out, const char *value);
147 
148 extern int git_submodule__map(
149 	git_repository *repo,
150 	git_strmap *map);
151 
152 /**
153  * Check whether a submodule's name is valid.
154  *
155  * Check the path against the path validity rules, either the filesystem
156  * defaults (like checkout does) or whichever you want to compare against.
157  *
158  * @param repo the repository which contains the submodule
159  * @param name the name to check
160  * @param flags the `GIT_PATH` flags to use for the check (0 to use filesystem defaults)
161  */
162 extern int git_submodule_name_is_valid(git_repository *repo, const char *name, int flags);
163 
164 #endif
165