Add new @ shortcut for HEAD
Typing 'HEAD' is tedious, especially when we can use '@' instead.
The reason for choosing '@' is that it follows naturally from the
ref@op syntax (e.g. HEAD@{u}), except we have no ref, and no
operation, and when we don't have those, it makes sens to assume
'HEAD'.
So now we can use 'git show @~1', and all that goody goodness.
Until now '@' was a valid name, but it conflicts with this idea, so
let's make it invalid. Probably very few people, if any, used this name.
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
			
			
				maint
			
			
		
							parent
							
								
									cf99a761d3
								
							
						
					
					
						commit
						9ba89f484e
					
				|  | @ -54,6 +54,8 @@ Git imposes the following rules on how references are named: | |||
|  | ||||
| . They cannot contain a sequence `@{`. | ||||
|  | ||||
| . They cannot be the single character `@`. | ||||
|  | ||||
| . They cannot contain a `\`. | ||||
|  | ||||
| These rules make it easy for shell script based tools to parse | ||||
|  |  | |||
|  | @ -58,6 +58,9 @@ the '$GIT_DIR/refs' directory or from the '$GIT_DIR/packed-refs' file. | |||
| While the ref name encoding is unspecified, UTF-8 is preferred as | ||||
| some output processing may assume ref names in UTF-8. | ||||
|  | ||||
| '@':: | ||||
|   '@' alone is a shortcut for 'HEAD'. | ||||
|  | ||||
| '<refname>@\{<date>\}', e.g. 'master@\{yesterday\}', 'HEAD@\{5 minutes ago\}':: | ||||
|   A ref followed by the suffix '@' with a date specification | ||||
|   enclosed in a brace | ||||
|  |  | |||
							
								
								
									
										4
									
								
								refs.c
								
								
								
								
							
							
						
						
									
										4
									
								
								refs.c
								
								
								
								
							|  | @ -72,6 +72,10 @@ int check_refname_format(const char *refname, int flags) | |||
| { | ||||
| 	int component_len, component_count = 0; | ||||
|  | ||||
| 	if (!strcmp(refname, "@")) | ||||
| 		/* Refname is a single character '@'. */ | ||||
| 		return -1; | ||||
|  | ||||
| 	while (1) { | ||||
| 		/* We are at the start of a path component. */ | ||||
| 		component_len = check_refname_component(refname, flags); | ||||
|  |  | |||
							
								
								
									
										28
									
								
								sha1_name.c
								
								
								
								
							
							
						
						
									
										28
									
								
								sha1_name.c
								
								
								
								
							|  | @ -1004,6 +1004,28 @@ int get_sha1_mb(const char *name, unsigned char *sha1) | |||
| 	return st; | ||||
| } | ||||
|  | ||||
| /* parse @something syntax, when 'something' is not {.*} */ | ||||
| static int interpret_empty_at(const char *name, int namelen, int len, struct strbuf *buf) | ||||
| { | ||||
| 	const char *next; | ||||
|  | ||||
| 	if (len || name[1] == '{') | ||||
| 		return -1; | ||||
|  | ||||
| 	/* make sure it's a single @, or @@{.*}, not @foo */ | ||||
| 	next = strchr(name + len + 1, '@'); | ||||
| 	if (next && next[1] != '{') | ||||
| 		return -1; | ||||
| 	if (!next) | ||||
| 		next = name + namelen; | ||||
| 	if (next != name + 1) | ||||
| 		return -1; | ||||
|  | ||||
| 	strbuf_reset(buf); | ||||
| 	strbuf_add(buf, "HEAD", 4); | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int reinterpret(const char *name, int namelen, int len, struct strbuf *buf) | ||||
| { | ||||
| 	/* we have extra data, which might need further processing */ | ||||
|  | @ -1068,9 +1090,15 @@ int interpret_branch_name(const char *name, int namelen, struct strbuf *buf) | |||
| 	cp = strchr(name, '@'); | ||||
| 	if (!cp) | ||||
| 		return -1; | ||||
|  | ||||
| 	len = interpret_empty_at(name, namelen, cp - name, buf); | ||||
| 	if (len > 0) | ||||
| 		return reinterpret(name, namelen, len, buf); | ||||
|  | ||||
| 	tmp_len = upstream_mark(cp, namelen - (cp - name)); | ||||
| 	if (!tmp_len) | ||||
| 		return -1; | ||||
|  | ||||
| 	len = cp + tmp_len - name; | ||||
| 	cp = xstrndup(name, cp - name); | ||||
| 	upstream = branch_get(*cp ? cp : NULL); | ||||
|  |  | |||
|  | @ -32,6 +32,9 @@ test_expect_success 'setup' ' | |||
| 	git checkout -b upstream-branch && | ||||
| 	test_commit upstream-one && | ||||
| 	test_commit upstream-two && | ||||
| 	git checkout -b @/at-test && | ||||
| 	git checkout -b @@/at-test && | ||||
| 	git checkout -b @at-test && | ||||
| 	git checkout -b old-branch && | ||||
| 	test_commit old-one && | ||||
| 	test_commit old-two && | ||||
|  | @ -55,6 +58,11 @@ check "HEAD@{u}" ref refs/heads/upstream-branch | |||
| check "@{u}@{1}" commit upstream-one | ||||
| check "@{-1}@{u}" ref refs/heads/master | ||||
| check "@{-1}@{u}@{1}" commit master-one | ||||
| check "@" commit new-two | ||||
| check "@@{u}" ref refs/heads/upstream-branch | ||||
| check "@@/at-test" ref refs/heads/@@/at-test | ||||
| check "@/at-test" ref refs/heads/@/at-test | ||||
| check "@at-test" ref refs/heads/@at-test | ||||
| nonsense "@{u}@{-1}" | ||||
| nonsense "@{0}@{0}" | ||||
| nonsense "@{1}@{u}" | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Felipe Contreras
						Felipe Contreras