References

CLOS class reference
Superclass:

[‘T’]

Metaclass:

standard-class

Creating

Method (make-object (class (eq REFERENCE)) (id/name T) (repository T) &key url type force target signature message log-message &allow-other-keys)

Create a reference to TARGET. The type of reference depends on TYPE. If TYPE is :OID the value of TARGET should be an OID and a direct reference is created. If TYPE is :SYMBOLIC, a symbolic reference is created and TARGET should be a string. SIGNATURE should be a signature plist. LOG-MESSAGE should be a string.

If FORCE is t the reference will be created, even if a reference with the same name already exists. If FORCE is nil, it will return an error if that is the case.

See also: make-object

Accessing

To access a single reference get object can be used, but the fully qualified name of the reference must be specified.

Method (get-object (class (eq REFERENCE)) (id/name T) (repository T))

Find a reference by its full name e.g.: refs/heads/master Note that this function name clashes with the generic lookup function. We need to figure this out by using the type argument to do dispatch.

GIT> (get-object 'reference "refs/heads/master"
         (open-repository (merge-pathnames #p"projects/lisp/cl-git"
                                           (user-homedir-pathname))))
#<REFERENCE refs/heads/master {100BA0E543}>

See also: get-object

Details

Method (full-name (object REFERENCE))

Return the full path to the REFERENCE as a STRING.

GIT> (full-name
       (get-object 'reference "refs/heads/master"
                     (open-repository (merge-pathnames #p"projects/lisp/cl-git"
                                                       (user-homedir-pathname)))))
"refs/heads/master"

See also: full-name

Method (short-name (object REFERENCE))

Return the short name of the REFERENCE as a STRING. This could for example be the text “master” or “HEAD”.

GIT> (short-name
       (get-object 'reference "refs/heads/master"
                     (open-repository (merge-pathnames #p"projects/lisp/cl-git"
                                                       (user-homedir-pathname)))))
"master"

See also: short-name

Listing

Method (list-objects (class (eq REFERENCE)) (repository T) &key test test-not)

List all the refs the returned list can be filtered using a PREDICATE.

To list all the references present in a repository we use the function LIST-OBJECTS and tell to only list objects of type REFERENCE.

GIT> (list-objects 'reference
                   (open-repository "/home/russell/projects/lisp/cl-git/"))
(#<REFERENCE refs/remotes/origin/master (weak) {1004A66973}>
 #<REFERENCE refs/remotes/origin/0.17.0 (weak) {1004A66C53}>
 #<REFERENCE refs/remotes/origin/0.18.0 (weak) {1004A66DC3}>
 #<REFERENCE refs/remotes/origin/HEAD (weak) {1004A66F33}>
 #<REFERENCE refs/tags/0.1 (weak) {1004A677D3}>
 #<REFERENCE refs/heads/master (weak) {1004A67943}>
 #<REFERENCE refs/heads/0.18.0 (weak) {1004A67C23}>)

See also: list-objects

Filtering Results

Generic (branch-p reference)
(branch-p (reference REFERENCE))
(branch-p (reference STRING))

Return T if the reference is within the git heads namespace.

GIT> (list-objects 'reference repo :test #'branch-p)
(#<REFERENCE refs/heads/master (weak) {1004A67943}>
 #<REFERENCE refs/heads/0.18.0 (weak) {1004A67C23}>)
Generic (symbolic-p reference)
(symbolic-p (reference REFERENCE))

Return T if the reference is symbolic.

GIT> (list-objects 'reference repo :test #'symbolic-p)
(#<REFERENCE refs/remotes/origin/HEAD (weak) {1004A66F33}>)
Generic (remote-p reference)
(remote-p (reference REFERENCE))
(remote-p (reference STRING))

Return T if the reference is within the git remotes namespace.

GIT> (list-objects 'reference repo :test #'remote-p)
(#<REFERENCE refs/remotes/origin/master (weak) {1004A66973}>
 #<REFERENCE refs/remotes/origin/0.17.0 (weak) {1004A66C53}>
 #<REFERENCE refs/remotes/origin/0.18.0 (weak) {1004A66DC3}>
 #<REFERENCE refs/remotes/origin/HEAD (weak) {1004A66F33}>)
Generic (head-p branch)
(head-p (branch REFERENCE))

Returns T if the current HEAD points to this branch. This means that this is the branch that is checked out.

GIT> (list-objects 'reference repo :test #'head-p)
(#<REFERENCE refs/remotes/origin/master (weak) {1004A66973}>)

Resolving

Generic (target object)
(target (reference REFERENCE))
(target (tag TAG))
(setf (target (reference REFERENCE) &key signature (log-message "")) (val T))

Returns the target of OBJECT.

GIT> (target (get-object 'reference "HEAD"
         (open-repository (merge-pathnames #p"projects/ecl"
                                           (user-homedir-pathname)))))
#<REFERENCE refs/heads/master {1007CD3D53}>
Generic (resolve object &optional stop-at)
(resolve (object REFERENCE) &OPTIONAL (STOP-AT ' (COMMIT TAG)))
(resolve (object TAG) &OPTIONAL (STOP-AT ' (COMMIT)))
GIT> (resolve (get-object 'reference "HEAD"
         (open-repository (merge-pathnames #p"projects/ecl"
                                           (user-homedir-pathname)))))
#<COMMIT E92F8C418F626A5041FC242C0FB1CEB1BEC4D61B {1007497AB3}>
(#<REFERENCE refs/heads/master {1007496723}> #<REFERENCE HEAD {1007495C53}>)

Branches

In libgit2 and in cl-git, branches are references but in a different namespace. Which means that, the same function used to list references is used to list branches. To limit the references to branches only use BRANCH-P.

Generic (branch-p reference)
(branch-p (reference REFERENCE))
(branch-p (reference STRING))

Return T if the reference is within the git heads namespace.

GIT> (list-objects 'reference repo :test #'branch-p)
(#<REFERENCE refs/heads/master (weak) {10051CF843}>
 #<REFERENCE refs/heads/0.18.0 (weak) {10051CF9B3}>)

So a branch is a special kind of reference. In git there are a few differences between branches and references:

  • branches are stored in a special location in the .git folder

  • branches are moved/updated during a git commit operation

For a user of the git repository, this small difference between branches and normal references makes a huge difference. You commit on branches and merge different branches. But typically you will not deal with non branch references.

Listing remote branches can be done with.

GIT> (list-objects 'reference (open-repository #p"/home/russell/projects/ecl/")
                   :test #'remote-p)
(#<REFERENCE refs/remotes/origin/master (weak) {1007A39EA3}>
 #<REFERENCE refs/remotes/origin/HEAD (weak) {1007A3A2F3}>)