1313
1414__all__ = ["Reference" ]
1515
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+
1628
1729class Reference (SymbolicReference , LazyMixin , Iterable ):
1830 """Represents a named reference to any object. Subclasses may apply restrictions though,
@@ -22,20 +34,24 @@ class Reference(SymbolicReference, LazyMixin, Iterable):
2234 _resolve_ref_on_create = True
2335 _common_path_default = "refs"
2436
25- def __init__ (self , repo , path ):
37+ def __init__ (self , repo , path , check_path = True ):
2638 """Initialize this instance
2739 :param repo: Our parent repository
2840
2941 :param path:
3042 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 ))
3448 super (Reference , self ).__init__ (repo , path )
3549
3650
3751 def __str__ (self ):
3852 return self .name
53+
54+ #{ Interface
3955
4056 def set_object (self , object , logmsg = None ):
4157 """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):
8298 """Equivalent to SymbolicReference.iter_items, but will return non-detached
8399 references as well."""
84100 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