ctucx.git: nimgit

[nimlang] nim-wrapper for libgit2

commit 0219741ae61a0a3b3ed80d7fe562f5dfc1869cb4
parent 300a9f8364b032e7f4a3b6b01a6008428ec3ca17
Author: Leah (ctucx) <leah@ctu.cx>
Date: Tue, 16 Mar 2021 13:48:17 +0100

add branch iterator and helpers
6 files changed, 79 insertions(+), 3 deletions(-)
M
.gitignore
|
3
+++
A
listAllBranches.nim
|
25
+++++++++++++++++++++++++
M
nimgit.nimble
|
2
+-
M
nimgit/reference.nim
|
42
+++++++++++++++++++++++++++++++++++++++++-
M
nimgit/types.nim
|
9
++++++++-
M
showLastCommit.nim
|
1
+
diff --git a/.gitignore b/.gitignore
@@ -2,3 +2,5 @@ libgit2.so
 listAllCommits
 listAllRefs
 showLastCommit
+
+listAllBranches+
\ No newline at end of file
diff --git a/listAllBranches.nim b/listAllBranches.nim
@@ -0,0 +1,24 @@
+import os
+import nimgit
+
+if paramCount() == 0:
+    echo "No git-repo given."
+    quit(QuitFailure)
+
+discard git_libgit2_init()
+
+try:
+    let gitRepository     = openGitRepository(paramStr(1))
+
+    for branch in gitRepository.branches(branchAll):
+        if branch.isLocalBranch():
+            echo "local: " & $branch
+
+        if branch.isRemoteBranch():
+            echo "remote: " & $branch
+
+        free(branch)
+
+    free(gitRepository)
+except:
+    echo "Error:\n", getCurrentExceptionMsg()+
\ No newline at end of file
diff --git a/nimgit.nimble b/nimgit.nimble
@@ -7,7 +7,7 @@ license       = "MIT"
 srcDir        = "./"
 installDirs   = @["nimgit"]
 installFiles  = @["nimgit.nim"]
-bin           = @["showLastCommit", "listAllCommits", "listAllFiles", "listAllRefs"]
+bin           = @["showLastCommit", "listAllCommits", "listAllFiles", "listAllRefs", "listAllBranches"]
 
 
 # Dependencies
diff --git a/nimgit/reference.nim b/nimgit/reference.nim
@@ -1,6 +1,17 @@
 import nimgit2
 import types, free, objects
 
+proc getShorthand* (reference: GitReference): string = 
+    result = $git_reference_shorthand(reference)
+
+proc `$`* (reference: GitReference): string = reference.getShorthand()
+
+proc isLocalBranch* (reference: GitReference): bool = cast[bool](git_reference_is_branch(reference))
+
+proc isRemoteBranch* (reference: GitReference): bool = cast[bool](git_reference_is_remote(reference))
+
+proc isTag* (reference: GitReference): bool = cast[bool](git_reference_is_tag(reference))
+
 proc getGitReferenceNames* (repo: GitRepository): seq[string] =
     var gitRefsArr: git_strarray
 

@@ -13,12 +24,14 @@ proc getGitReferenceNames* (repo: GitRepository): seq[string] =
     
     git_strarray_dispose(addr gitRefsArr);
 
+
 proc lookupGitReference* (repo: GitRepository, refName: string): GitReference =     
     let error = git_reference_lookup(addr result, repo, cstring(refName))
 
     if error != 0:
         raise newException(CatchableError, "Lookup failed: " & $error.getResultCode)
 
+
 proc createRevisionWalker* (repo: GitRepository, sort: git_sort_t = GIT_SORT_TOPOLOGICAL): GitRevisionWalker =
     var error: cint
 

@@ -32,6 +45,7 @@ proc createRevisionWalker* (repo: GitRepository, sort: git_sort_t = GIT_SORT_TOP
     if error != 0:
         raise newException(CatchableError, "Cannot set sorting: " & $error.getResultCode)
 
+
 proc createRevisionWalker* (repo: GitRepository, reference: string, sort: git_sort_t = GIT_SORT_TOPOLOGICAL): GitRevisionWalker =
     var error: cint
     var gitWalker = repo.createRevisionWalker(sort)

@@ -43,6 +57,7 @@ proc createRevisionWalker* (repo: GitRepository, reference: string, sort: git_so
 
     result = gitWalker
 
+
 proc next* (walker: GitRevisionWalker): GitObjectId =
     var error: cint
     var objectId = initGitObjectId()

@@ -56,7 +71,6 @@ proc next* (walker: GitRevisionWalker): GitObjectId =
     result = objectId
 
 
-
 iterator walk* (walker: GitRevisionWalker): GitObjectId =
     block:
         try:

@@ -67,3 +81,29 @@ iterator walk* (walker: GitRevisionWalker): GitObjectId =
                 break
             else:
                 raise newException(CatchableError, getCurrentExceptionMsg())
+
+
+iterator branches* (repo: GitRepository, branchType: GitBranchType = branchLocal): GitReference =
+    var
+      cbranchType = cast[git_branch_t](branchType.ord)
+      branchIterator: GitBranchIterator
+
+    let error = git_branch_iterator_new(addr branchIterator, repo, cbranchType).getResultCode
+
+    if error != grcOk:
+        free(branchIterator)
+        raise newException(CatchableError, "Cannot create branch iterator: " & $error)
+
+    while true:
+        var branch: GitReference
+        let code = git_branch_next(addr branch, addr cbranchType, branchIterator).getResultCode
+        case code:
+            of grcOk:
+                yield branch
+
+            of grcIterOver:
+                free(branchIterator)
+                break
+
+            else:
+                raise newException(CatchableError, "iteration error: " & $error)
diff --git a/nimgit/types.nim b/nimgit/types.nim
@@ -7,7 +7,8 @@ type
     GitObjectId*        = ptr git_oid
     GitCommit*          = ptr git_commit
     GitReference*       = ptr git_reference
-    GitRevisionWalker* = ptr git_revwalk
+    GitRevisionWalker*  = ptr git_revwalk
+    GitBranchIterator*  = ptr git_branch_iterator
 
     GitTime* = object
         time*     : Time

@@ -19,6 +20,12 @@ type
         email*  : string
         `when`* : GitTime
 
+
+    GitBranchType* = enum
+        branchLocal  = (GIT_BRANCH_LOCAL, "local")
+        branchRemote = (GIT_BRANCH_REMOTE, "remote")
+        branchAll    = (GIT_BRANCH_ALL, "all")
+
     GitReturnCode* = enum
         grcApplyFail       = (GIT_EAPPLYFAIL, "patch failed")
         grcIndexDirty      = (GIT_EINDEXDIRTY, "dirty index")
diff --git a/showLastCommit.nim b/showLastCommit.nim
@@ -22,6 +22,7 @@ try:
     echo "message: " & commit.getSummary()
 
     free(commit);
+    free(headCommit);
     free(gitRepository)
 
 except: