@@ -42,9 +42,13 @@ def short_to_long(odb, hexsha):
42
42
# END exception handling
43
43
44
44
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
+ """
48
52
hexsha = None
49
53
50
54
# is it a hexsha ? Try the most common ones, which is 7 to 40
@@ -59,12 +63,20 @@ def name_to_object(repo, name):
59
63
for base in ('%s' , 'refs/%s' , 'refs/tags/%s' , 'refs/heads/%s' , 'refs/remotes/%s' , 'refs/remotes/%s/HEAD' ):
60
64
try :
61
65
hexsha = SymbolicReference .dereference_recursive (repo , base % name )
66
+ if return_ref :
67
+ return SymbolicReference (repo , base % name )
68
+ #END handle symbolic ref
62
69
break
63
70
except ValueError :
64
71
pass
65
72
# END for each base
66
73
# 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
+
68
80
# tried everything ? fail
69
81
if hexsha is None :
70
82
raise BadObject (name )
@@ -101,9 +113,6 @@ def rev_parse(repo, rev):
101
113
:note: Currently there is no access to the rev-log, rev-specs may only contain
102
114
topological tokens such ~ and ^.
103
115
: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
-
107
116
108
117
# colon search mode ?
109
118
if rev .startswith (':/' ):
@@ -112,22 +121,37 @@ def rev_parse(repo, rev):
112
121
# END handle search
113
122
114
123
obj = None
124
+ ref = None
115
125
output_type = "commit"
116
126
start = 0
117
127
parsed_to = 0
118
128
lr = len (rev )
119
129
while start < lr :
120
- if rev [start ] not in "^~:" :
130
+ if rev [start ] not in "^~:@ " :
121
131
start += 1
122
132
continue
123
133
# END handle start
124
134
135
+ token = rev [start ]
136
+
125
137
if obj is None :
126
138
# 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
128
152
# END initialize obj on first token
129
153
130
- token = rev [ start ]
154
+
131
155
start += 1
132
156
133
157
# try to parse {type}
@@ -153,6 +177,24 @@ def rev_parse(repo, rev):
153
177
# cannot do anything for non-tags
154
178
pass
155
179
# 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
156
198
else :
157
199
raise ValueError ("Invalid output type: %s ( in %s )" % (output_type , rev ))
158
200
# END handle output type
0 commit comments