13
13
14
14
__all__ = ["Reference" ]
15
15
16
+ #{ Utilities
17
+ def require_remote_ref_path (func ):
18
+ """A decorator raising a TypeError if we are not a valid remote, based on the path"""
19
+ def wrapper (self , * args ):
20
+ if not self .path .startswith (self ._remote_common_path_default + "/" ):
21
+ raise ValueError ("ref path does not point to a remote reference: %s" % path )
22
+ return func (self , * args )
23
+ #END wrapper
24
+ wrapper .__name__ = func .__name__
25
+ return wrapper
26
+ #}END utilites
27
+
16
28
17
29
class Reference (SymbolicReference , LazyMixin , Iterable ):
18
30
"""Represents a named reference to any object. Subclasses may apply restrictions though,
@@ -22,20 +34,24 @@ class Reference(SymbolicReference, LazyMixin, Iterable):
22
34
_resolve_ref_on_create = True
23
35
_common_path_default = "refs"
24
36
25
- def __init__ (self , repo , path ):
37
+ def __init__ (self , repo , path , check_path = True ):
26
38
"""Initialize this instance
27
39
:param repo: Our parent repository
28
40
29
41
:param path:
30
42
Path relative to the .git/ directory pointing to the ref in question, i.e.
31
- refs/heads/master"""
32
- if not path .startswith (self ._common_path_default + '/' ):
33
- raise ValueError ("Cannot instantiate %r from path %s" % ( self .__class__ .__name__ , path ))
43
+ refs/heads/master
44
+ :param check_path: if False, you can provide any path. Otherwise the path must start with the
45
+ default path prefix of this type."""
46
+ if check_path and not path .startswith (self ._common_path_default + '/' ):
47
+ raise ValueError ("Cannot instantiate %r from path %s" % (self .__class__ .__name__ , path ))
34
48
super (Reference , self ).__init__ (repo , path )
35
49
36
50
37
51
def __str__ (self ):
38
52
return self .name
53
+
54
+ #{ Interface
39
55
40
56
def set_object (self , object , logmsg = None ):
41
57
"""Special version which checks if the head-log needs an update as well"""
@@ -82,3 +98,30 @@ def iter_items(cls, repo, common_path = None):
82
98
"""Equivalent to SymbolicReference.iter_items, but will return non-detached
83
99
references as well."""
84
100
return cls ._iter_items (repo , common_path )
101
+
102
+ #}END interface
103
+
104
+
105
+ #{ Remote Interface
106
+
107
+ @property
108
+ @require_remote_ref_path
109
+ def remote_name (self ):
110
+ """
111
+ :return:
112
+ Name of the remote we are a reference of, such as 'origin' for a reference
113
+ named 'origin/master'"""
114
+ tokens = self .path .split ('/' )
115
+ # /refs/remotes/<remote name>/<branch_name>
116
+ return tokens [2 ]
117
+
118
+ @property
119
+ @require_remote_ref_path
120
+ def remote_head (self ):
121
+ """:return: Name of the remote head itself, i.e. master.
122
+ :note: The returned name is usually not qualified enough to uniquely identify
123
+ a branch"""
124
+ tokens = self .path .split ('/' )
125
+ return '/' .join (tokens [3 :])
126
+
127
+ #} END remote interface
0 commit comments