@@ -42,9 +42,13 @@ def short_to_long(odb, hexsha):
4242# END exception handling
4343
4444
45- def name_to_object (repo ,name ):
46- """:return: object specified by the given name, hexshas ( short and long )
47- as well as references are supported"""
45+ def name_to_object (repo ,name ,return_ref = False ):
46+ """
47+ :return: object specified by the given name, hexshas ( short and long )
48+ as well as references are supported
49+ :param return_ref: if name specifies a reference, we will return the reference
50+ instead of the object. Otherwise it will raise BadObject
51+ """
4852hexsha = None
4953
5054# is it a hexsha ? Try the most common ones, which is 7 to 40
@@ -59,12 +63,20 @@ def name_to_object(repo, name):
5963for base in ('%s' ,'refs/%s' ,'refs/tags/%s' ,'refs/heads/%s' ,'refs/remotes/%s' ,'refs/remotes/%s/HEAD' ):
6064try :
6165hexsha = SymbolicReference .dereference_recursive (repo ,base % name )
66+ if return_ref :
67+ return SymbolicReference (repo ,base % name )
68+ #END handle symbolic ref
6269break
6370except ValueError :
6471pass
6572# END for each base
6673# END handle hexsha
67-
74+
75+ # didn't find any ref, this is an error
76+ if return_ref :
77+ raise BadObject ("Couldn't find reference named %r" % name )
78+ #END handle return ref
79+
6880# tried everything ? fail
6981if hexsha is None :
7082raise BadObject (name )
@@ -101,9 +113,6 @@ def rev_parse(repo, rev):
101113:note: Currently there is no access to the rev-log, rev-specs may only contain
102114topological tokens such ~ and ^.
103115:raise BadObject: if the given revision could not be found"""
104- if '@' in rev :
105- raise ValueError ("There is no rev-log support yet" )
106-
107116
108117# colon search mode ?
109118if rev .startswith (':/' ):
@@ -112,22 +121,37 @@ def rev_parse(repo, rev):
112121# END handle search
113122
114123obj = None
124+ ref = None
115125output_type = "commit"
116126start = 0
117127parsed_to = 0
118128lr = len (rev )
119129while start < lr :
120- if rev [start ]not in "^~:" :
130+ if rev [start ]not in "^~:@ " :
121131start += 1
122132continue
123133# END handle start
124134
135+ token = rev [start ]
136+
125137if obj is None :
126138# token is a rev name
127- obj = name_to_object (repo ,rev [:start ])
139+ if start == 0 :
140+ ref = repo .head .ref
141+ else :
142+ if token == '@' :
143+ ref = name_to_object (repo ,rev [:start ],return_ref = True )
144+ else :
145+ obj = name_to_object (repo ,rev [:start ])
146+ #END handle token
147+ #END handle refname
148+
149+ if ref is not None :
150+ obj = ref .commit
151+ #END handle ref
128152# END initialize obj on first token
129153
130- token = rev [ start ]
154+
131155start += 1
132156
133157# try to parse {type}
@@ -153,6 +177,24 @@ def rev_parse(repo, rev):
153177# cannot do anything for non-tags
154178pass
155179# END handle tag
180+ elif token == '@' :
181+ # try single int
182+ assert ref is not None ,"Requre Reference to access reflog"
183+ revlog_index = None
184+ try :
185+ # transform reversed index into the format of our revlog
186+ revlog_index = - (int (output_type )+ 1 )
187+ except ValueError :
188+ # TODO: Try to parse the other date options, using parse_date
189+ # maybe
190+ raise NotImplementedError ("Support for additional @{...} modes not implemented" )
191+ #END handle revlog index
192+
193+ entry = ref .log ()[revlog_index ]
194+ obj = Object .new_from_sha (repo ,hex_to_bin (entry .newhexsha ))
195+
196+ # make it pass the following checks
197+ output_type = None
156198else :
157199raise ValueError ("Invalid output type: %s ( in %s )" % (output_type ,rev ))
158200# END handle output type