References

type reference

Creating

method (make-object (class reference) (id/name T) (repository T) &key url (type :oid) force target &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.

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.

Specializers:
(reference common-lisp:t common-lisp:t)
(remote common-lisp:t common-lisp:t)

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 reference) (id/name T) (repository T))

Find a reference by its full name e.g.: ref/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 "ref/heads/master"
         (open-repository (merge-pathnames #p"projects/lisp/cl-git"
                                           (user-homedir-pathname))))
#<REFERENCE refs/heads/master {100BA0E543}>
Specializers:
(object common-lisp:t common-lisp:t)
(blob common-lisp:t common-lisp:t)
(commit common-lisp:t common-lisp:t)
(tree common-lisp:t common-lisp:t)
(odb-object common-lisp:t odb)
(remote common-lisp:t common-lisp:t)
(odb-object common-lisp:t repository)
(reference common-lisp:t common-lisp:t)
(tag common-lisp:t common-lisp:t)

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"
Specializers:
(reference)
(remote)
(tag)
(git-object)

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"
Specializers:
(reference)
(remote)
(tag)
(git-object)

Listing

method (list-objects (class 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}>)
Specializers:
((eql :oid) repository)
(remote common-lisp:t)
(tag common-lisp:t)
((eql :oid) odb)
(reference common-lisp:t)

Filtering Results

generic (branch-p reference)

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}>)
Specializers:
(common-lisp:string)
(reference)
generic (symbolic-p reference)

Return T if the reference is symbolic.

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

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}>)
Specializers:
(common-lisp:string)
(reference)
generic (head-p branch)

Returns t is 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}>)
Specializers:
(reference)

Resolving

method (target (object reference))

Returns the Object that this reference points to. If the reference is symbolic then the reference it points to will be returned.

GIT> (target (get-object 'reference "HEAD"
         (open-repository (merge-pathnames #p"projects/ecl"
                                           (user-homedir-pathname)))))
#<REFERENCE refs/heads/master {1007CD3D53}>
Specializers:
(reference)
(tag)

method (resolve (object reference) &optional stop-at)

Resolve the reference until the resulting object is a tag or commit. The accumulated result is calling TARGET repeatedly is returned as using VALUES. By default the resolving will stop when a COMMIT or TAG is found.

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}>)
Specializers:
(reference)
(tag)

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.

method (branch-p (reference reference))

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}>)
Specializers:
(common-lisp:string)
(reference)