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 <derrickstolee@github.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
							parent
							
								
									5797b13919
								
							
						
					
					
						commit
						b9342b3fd6
					
				|  | @ -185,6 +185,8 @@ void setup_git_env(const char *git_dir) | |||
| 	free(git_replace_ref_base); | ||||
| 	git_replace_ref_base = xstrdup(replace_ref_base ? replace_ref_base | ||||
| 							  : "refs/replace/"); | ||||
| 	update_ref_namespace(NAMESPACE_REPLACE, git_replace_ref_base); | ||||
|  | ||||
| 	free(git_namespace); | ||||
| 	git_namespace = expand_namespace(getenv(GIT_NAMESPACE_ENVIRONMENT)); | ||||
| 	shallow_file = getenv(GIT_SHALLOW_FILE_ENVIRONMENT); | ||||
|  |  | |||
							
								
								
									
										1
									
								
								notes.c
								
								
								
								
							
							
						
						
									
										1
									
								
								notes.c
								
								
								
								
							|  | @ -1005,6 +1005,7 @@ void init_notes(struct notes_tree *t, const char *notes_ref, | |||
|  | ||||
| 	if (!notes_ref) | ||||
| 		notes_ref = default_notes_ref(); | ||||
| 	update_ref_namespace(NAMESPACE_NOTES, xstrdup(notes_ref)); | ||||
|  | ||||
| 	if (!combine_notes) | ||||
| 		combine_notes = combine_notes_concatenate; | ||||
|  |  | |||
							
								
								
									
										83
									
								
								refs.c
								
								
								
								
							
							
						
						
									
										83
									
								
								refs.c
								
								
								
								
							|  | @ -20,6 +20,7 @@ | |||
| #include "repository.h" | ||||
| #include "sigchain.h" | ||||
| #include "date.h" | ||||
| #include "commit.h" | ||||
|  | ||||
| /* | ||||
|  * List of all available backends | ||||
|  | @ -56,6 +57,88 @@ static unsigned char refname_disposition[256] = { | |||
| 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 4, 4 | ||||
| }; | ||||
|  | ||||
| struct ref_namespace_info ref_namespace[] = { | ||||
| 	[NAMESPACE_HEAD] = { | ||||
| 		.ref = "HEAD", | ||||
| 		.decoration = DECORATION_REF_HEAD, | ||||
| 		.exact = 1, | ||||
| 	}, | ||||
| 	[NAMESPACE_BRANCHES] = { | ||||
| 		.ref = "refs/heads/", | ||||
| 		.decoration = DECORATION_REF_LOCAL, | ||||
| 	}, | ||||
| 	[NAMESPACE_TAGS] = { | ||||
| 		.ref = "refs/tags/", | ||||
| 		.decoration = DECORATION_REF_TAG, | ||||
| 	}, | ||||
| 	[NAMESPACE_REMOTE_REFS] = { | ||||
| 		/* | ||||
| 		 * The default refspec for new remotes copies refs from | ||||
| 		 * refs/heads/ on the remote into refs/remotes/<remote>/. | ||||
| 		 * As such, "refs/remotes/" has special handling. | ||||
| 		 */ | ||||
| 		.ref = "refs/remotes/", | ||||
| 		.decoration = DECORATION_REF_REMOTE, | ||||
| 	}, | ||||
| 	[NAMESPACE_STASH] = { | ||||
| 		/* | ||||
| 		 * The single ref "refs/stash" stores the latest stash. | ||||
| 		 * Older stashes can be found in the reflog. | ||||
| 		 */ | ||||
| 		.ref = "refs/stash", | ||||
| 		.exact = 1, | ||||
| 		.decoration = DECORATION_REF_STASH, | ||||
| 	}, | ||||
| 	[NAMESPACE_REPLACE] = { | ||||
| 		/* | ||||
| 		 * This namespace allows Git to act as if one object ID | ||||
| 		 * points to the content of another. Unlike the other | ||||
| 		 * ref namespaces, this one can be changed by the | ||||
| 		 * GIT_REPLACE_REF_BASE environment variable. This | ||||
| 		 * .namespace value will be overwritten in setup_git_env(). | ||||
| 		 */ | ||||
| 		.ref = "refs/replace/", | ||||
| 		.decoration = DECORATION_GRAFTED, | ||||
| 	}, | ||||
| 	[NAMESPACE_NOTES] = { | ||||
| 		/* | ||||
| 		 * The refs/notes/commit ref points to the tip of a | ||||
| 		 * parallel commit history that adds metadata to commits | ||||
| 		 * in the normal history. This ref can be overwritten | ||||
| 		 * by the core.notesRef config variable or the | ||||
| 		 * GIT_NOTES_REFS environment variable. | ||||
| 		 */ | ||||
| 		.ref = "refs/notes/commit", | ||||
| 		.exact = 1, | ||||
| 	}, | ||||
| 	[NAMESPACE_PREFETCH] = { | ||||
| 		/* | ||||
| 		 * Prefetch refs are written by the background 'fetch' | ||||
| 		 * maintenance task. It allows faster foreground fetches | ||||
| 		 * by advertising these previously-downloaded tips without | ||||
| 		 * updating refs/remotes/ without user intervention. | ||||
| 		 */ | ||||
| 		.ref = "refs/prefetch/", | ||||
| 	}, | ||||
| 	[NAMESPACE_REWRITTEN] = { | ||||
| 		/* | ||||
| 		 * Rewritten refs are used by the 'label' command in the | ||||
| 		 * sequencer. These are particularly useful during an | ||||
| 		 * interactive rebase that uses the 'merge' command. | ||||
| 		 */ | ||||
| 		.ref = "refs/rewritten/", | ||||
| 	}, | ||||
| }; | ||||
|  | ||||
| void update_ref_namespace(enum ref_namespace namespace, char *ref) | ||||
| { | ||||
| 	struct ref_namespace_info *info = &ref_namespace[namespace]; | ||||
| 	if (info->ref_updated) | ||||
| 		free(info->ref); | ||||
| 	info->ref = ref; | ||||
| 	info->ref_updated = 1; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Try to read one refname component from the front of refname. | ||||
|  * Return the length of the component found, or -1 if the component is | ||||
|  |  | |||
							
								
								
									
										46
									
								
								refs.h
								
								
								
								
							
							
						
						
									
										46
									
								
								refs.h
								
								
								
								
							|  | @ -2,6 +2,7 @@ | |||
| #define REFS_H | ||||
|  | ||||
| #include "cache.h" | ||||
| #include "commit.h" | ||||
|  | ||||
| struct object_id; | ||||
| struct ref_store; | ||||
|  | @ -930,4 +931,49 @@ struct ref_store *get_main_ref_store(struct repository *r); | |||
| struct ref_store *get_submodule_ref_store(const char *submodule); | ||||
| struct ref_store *get_worktree_ref_store(const struct worktree *wt); | ||||
|  | ||||
| /* | ||||
|  * Some of the names specified by refs have special meaning to Git. | ||||
|  * Organize these namespaces in a comon 'ref_namespace' array for | ||||
|  * reference from multiple places in the codebase. | ||||
|  */ | ||||
|  | ||||
| struct ref_namespace_info { | ||||
| 	char *ref; | ||||
| 	enum decoration_type decoration; | ||||
|  | ||||
| 	/* | ||||
| 	 * If 'exact' is true, then we must match the 'ref' exactly. | ||||
| 	 * Otherwise, use a prefix match. | ||||
| 	 * | ||||
| 	 * 'ref_updated' is for internal use. It represents whether the | ||||
| 	 * 'ref' value was replaced from its original literal version. | ||||
| 	 */ | ||||
| 	unsigned exact:1, | ||||
| 		 ref_updated:1; | ||||
| }; | ||||
|  | ||||
| enum ref_namespace { | ||||
| 	NAMESPACE_HEAD, | ||||
| 	NAMESPACE_BRANCHES, | ||||
| 	NAMESPACE_TAGS, | ||||
| 	NAMESPACE_REMOTE_REFS, | ||||
| 	NAMESPACE_STASH, | ||||
| 	NAMESPACE_REPLACE, | ||||
| 	NAMESPACE_NOTES, | ||||
| 	NAMESPACE_PREFETCH, | ||||
| 	NAMESPACE_REWRITTEN, | ||||
|  | ||||
| 	/* Must be last */ | ||||
| 	NAMESPACE__COUNT | ||||
| }; | ||||
|  | ||||
| /* See refs.c for the contents of this array. */ | ||||
| extern struct ref_namespace_info ref_namespace[NAMESPACE__COUNT]; | ||||
|  | ||||
| /* | ||||
|  * Some ref namespaces can be modified by config values or environment | ||||
|  * variables. Modify a namespace as specified by its ref_namespace key. | ||||
|  */ | ||||
| void update_ref_namespace(enum ref_namespace namespace, char *ref); | ||||
|  | ||||
| #endif /* REFS_H */ | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Derrick Stolee
						Derrick Stolee