Skip to content

Commit b9342b3

Browse files
derrickstoleegitster
authored andcommitted
refs: add array of ref namespaces
Git interprets different meanings to different refs based on their names. Some meanings are cosmetic, like how refs in 'refs/remotes/*' are colored differently from refs in 'refs/heads/*'. Others are more critical, such as how replace refs are interpreted. Before making behavior changes based on ref namespaces, collect all known ref namespaces into a array of ref_namespace_info structs. This array is indexed by the new ref_namespace enum for quick access. As of this change, this array is purely documentation. Future changes will add dependencies on this array. Signed-off-by: Derrick Stolee <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 5797b13 commit b9342b3

File tree

4 files changed

+132
-0
lines changed

4 files changed

+132
-0
lines changed

environment.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,8 @@ void setup_git_env(const char *git_dir)
185185
free(git_replace_ref_base);
186186
git_replace_ref_base = xstrdup(replace_ref_base ? replace_ref_base
187187
: "refs/replace/");
188+
update_ref_namespace(NAMESPACE_REPLACE, git_replace_ref_base);
189+
188190
free(git_namespace);
189191
git_namespace = expand_namespace(getenv(GIT_NAMESPACE_ENVIRONMENT));
190192
shallow_file = getenv(GIT_SHALLOW_FILE_ENVIRONMENT);

notes.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,6 +1005,7 @@ void init_notes(struct notes_tree *t, const char *notes_ref,
10051005

10061006
if (!notes_ref)
10071007
notes_ref = default_notes_ref();
1008+
update_ref_namespace(NAMESPACE_NOTES, xstrdup(notes_ref));
10081009

10091010
if (!combine_notes)
10101011
combine_notes = combine_notes_concatenate;

refs.c

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "repository.h"
2121
#include "sigchain.h"
2222
#include "date.h"
23+
#include "commit.h"
2324

2425
/*
2526
* List of all available backends
@@ -56,6 +57,88 @@ static unsigned char refname_disposition[256] = {
5657
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 4, 4
5758
};
5859

60+
struct ref_namespace_info ref_namespace[] = {
61+
[NAMESPACE_HEAD] = {
62+
.ref = "HEAD",
63+
.decoration = DECORATION_REF_HEAD,
64+
.exact = 1,
65+
},
66+
[NAMESPACE_BRANCHES] = {
67+
.ref = "refs/heads/",
68+
.decoration = DECORATION_REF_LOCAL,
69+
},
70+
[NAMESPACE_TAGS] = {
71+
.ref = "refs/tags/",
72+
.decoration = DECORATION_REF_TAG,
73+
},
74+
[NAMESPACE_REMOTE_REFS] = {
75+
/*
76+
* The default refspec for new remotes copies refs from
77+
* refs/heads/ on the remote into refs/remotes/<remote>/.
78+
* As such, "refs/remotes/" has special handling.
79+
*/
80+
.ref = "refs/remotes/",
81+
.decoration = DECORATION_REF_REMOTE,
82+
},
83+
[NAMESPACE_STASH] = {
84+
/*
85+
* The single ref "refs/stash" stores the latest stash.
86+
* Older stashes can be found in the reflog.
87+
*/
88+
.ref = "refs/stash",
89+
.exact = 1,
90+
.decoration = DECORATION_REF_STASH,
91+
},
92+
[NAMESPACE_REPLACE] = {
93+
/*
94+
* This namespace allows Git to act as if one object ID
95+
* points to the content of another. Unlike the other
96+
* ref namespaces, this one can be changed by the
97+
* GIT_REPLACE_REF_BASE environment variable. This
98+
* .namespace value will be overwritten in setup_git_env().
99+
*/
100+
.ref = "refs/replace/",
101+
.decoration = DECORATION_GRAFTED,
102+
},
103+
[NAMESPACE_NOTES] = {
104+
/*
105+
* The refs/notes/commit ref points to the tip of a
106+
* parallel commit history that adds metadata to commits
107+
* in the normal history. This ref can be overwritten
108+
* by the core.notesRef config variable or the
109+
* GIT_NOTES_REFS environment variable.
110+
*/
111+
.ref = "refs/notes/commit",
112+
.exact = 1,
113+
},
114+
[NAMESPACE_PREFETCH] = {
115+
/*
116+
* Prefetch refs are written by the background 'fetch'
117+
* maintenance task. It allows faster foreground fetches
118+
* by advertising these previously-downloaded tips without
119+
* updating refs/remotes/ without user intervention.
120+
*/
121+
.ref = "refs/prefetch/",
122+
},
123+
[NAMESPACE_REWRITTEN] = {
124+
/*
125+
* Rewritten refs are used by the 'label' command in the
126+
* sequencer. These are particularly useful during an
127+
* interactive rebase that uses the 'merge' command.
128+
*/
129+
.ref = "refs/rewritten/",
130+
},
131+
};
132+
133+
void update_ref_namespace(enum ref_namespace namespace, char *ref)
134+
{
135+
struct ref_namespace_info *info = &ref_namespace[namespace];
136+
if (info->ref_updated)
137+
free(info->ref);
138+
info->ref = ref;
139+
info->ref_updated = 1;
140+
}
141+
59142
/*
60143
* Try to read one refname component from the front of refname.
61144
* Return the length of the component found, or -1 if the component is

refs.h

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define REFS_H
33

44
#include "cache.h"
5+
#include "commit.h"
56

67
struct object_id;
78
struct ref_store;
@@ -930,4 +931,49 @@ struct ref_store *get_main_ref_store(struct repository *r);
930931
struct ref_store *get_submodule_ref_store(const char *submodule);
931932
struct ref_store *get_worktree_ref_store(const struct worktree *wt);
932933

934+
/*
935+
* Some of the names specified by refs have special meaning to Git.
936+
* Organize these namespaces in a comon 'ref_namespace' array for
937+
* reference from multiple places in the codebase.
938+
*/
939+
940+
struct ref_namespace_info {
941+
char *ref;
942+
enum decoration_type decoration;
943+
944+
/*
945+
* If 'exact' is true, then we must match the 'ref' exactly.
946+
* Otherwise, use a prefix match.
947+
*
948+
* 'ref_updated' is for internal use. It represents whether the
949+
* 'ref' value was replaced from its original literal version.
950+
*/
951+
unsigned exact:1,
952+
ref_updated:1;
953+
};
954+
955+
enum ref_namespace {
956+
NAMESPACE_HEAD,
957+
NAMESPACE_BRANCHES,
958+
NAMESPACE_TAGS,
959+
NAMESPACE_REMOTE_REFS,
960+
NAMESPACE_STASH,
961+
NAMESPACE_REPLACE,
962+
NAMESPACE_NOTES,
963+
NAMESPACE_PREFETCH,
964+
NAMESPACE_REWRITTEN,
965+
966+
/* Must be last */
967+
NAMESPACE__COUNT
968+
};
969+
970+
/* See refs.c for the contents of this array. */
971+
extern struct ref_namespace_info ref_namespace[NAMESPACE__COUNT];
972+
973+
/*
974+
* Some ref namespaces can be modified by config values or environment
975+
* variables. Modify a namespace as specified by its ref_namespace key.
976+
*/
977+
void update_ref_namespace(enum ref_namespace namespace, char *ref);
978+
933979
#endif /* REFS_H */

0 commit comments

Comments
 (0)