develop.gittools #
Git Tools Module
A comprehensive Git management module for V that provides high-level abstractions for Git operations, repository management, and automation of common Git workflows.
Features
- Repository management (clone, load, delete)
- Branch operations (create, switch, checkout)
- Tag management (create, switch, verify)
- Change tracking and commits
- Remote operations (push, pull)
- SSH key integration
- Submodule support
- Repository status tracking
- Light cloning option for large repositories
Basic Usage
Repository Management
import freeflowuniverse.crystallib.develop.gittools
// Initialize with code root directory
mut gs := gittools.new(coderoot: '~/code')!
// Clone a repository
mut repo := gs.clone(GitCloneArgs{
url: 'git@github.com:username/repo.git'
sshkey: 'deploy_key' // Optional SSH key name
})!
// Or get existing repository
mut repo := gs.get_repo(name: 'existing_repo')!
// Delete repository
repo.delete()!
Branch Operations
// Create and switch to new branch
repo.branch_create('feature-branch')!
repo.branch_switch('feature-branch')!
// Check status and commit changes
if repo.has_changes() {
repo.commit('feat: Add new feature')!
repo.push()!
}
// Pull latest changes
repo.pull()!
// Pull with submodules
repo.pull(submodules: true)!
Tag Management
// Create a new tag
repo.tag_create('v1.0.0')!
// Switch to tag
repo.tag_switch('v1.0.0')!
// Check if tag exists
exists := repo.tag_exists('v1.0.0')!
// Get tag information
if repo.status_local.tag == 'v1.0.0' {
// Currently on tag v1.0.0
}
Advanced Features
SSH Key Integration
// Clone with SSH key
mut repo := gs.clone(GitCloneArgs{
url: 'git@github.com:username/repo.git'
sshkey: 'deploy_key'
})!
// Set SSH key for existing repository
repo.set_sshkey('deploy_key')!
Repository Status
// Update repository status
repo.status_update()!
// Check various status conditions
if repo.need_commit() {
// Has uncommitted changes
}
if repo.need_push_or_pull() {
// Has unpushed/unpulled changes
}
if repo.need_checkout() {
// Needs to checkout different branch/tag
}
Change Management
// Check for changes
if repo.has_changes() {
// Handle changes
}
// Reset all changes
repo.reset()!
// or
repo.remove_changes()!
// Update submodules
repo.update_submodules()!
Repository Configuration
GitRepo Structure
pub struct GitRepo {
pub mut:
provider string // e.g., github.com
account string // Git account name
name string // Repository name
status_remote GitRepoStatusRemote // Remote repository status
status_local GitRepoStatusLocal // Local repository status
status_wanted GitRepoStatusWanted // Desired status
config GitRepoConfig // Repository configuration
deploysshkey string // SSH key for git operations
}
Status Tracking
// Remote Status
pub struct GitRepoStatusRemote {
pub mut:
ref_default string // Default branch hash
branches map[string]string // Branch name -> commit hash
tags map[string]string // Tag name -> commit hash
}
// Local Status
pub struct GitRepoStatusLocal {
pub mut:
branches map[string]string // Branch name -> commit hash
branch string // Current branch
tag string // Current tag
}
// Desired Status
pub struct GitRepoStatusWanted {
pub mut:
branch string
tag string
url string // Remote repository URL
readonly bool // Prevent push/commit operations
}
Error Handling
The module provides comprehensive error handling:
// Clone with error handling
mut repo := gs.clone(url: 'invalid_url') or {
println('Clone failed: ${err}')
return
}
// Commit with error handling
repo.commit('feat: New feature') or {
if err.msg().contains('nothing to commit') {
println('No changes to commit')
} else {
println('Commit failed: ${err}')
}
return
}
Testing
Run the test suite:
v -enable-globals test crystallib/develop/gittools/tests/
Notes
- SSH keys should be properly configured in
~/.ssh/
- For readonly repositories, all local changes will be reset on pull
- Light cloning option (
config.light: true
) creates shallow clones - Repository status is automatically cached and updated
- Submodules are handled recursively when specified
- All operations maintain repository consistency
Constants #
const gitcmds = 'clone,commit,pull,push,delete,reload,list,edit,sourcetree,cd'
fn cachereset #
fn cachereset() !
Reset all caches and configurations for all Git repositories.
fn configreset #
fn configreset() !
Reset the configuration cache for Git structures.
fn get #
fn get(args_ GitStructureArgGet) !&GitStructure
Retrieve a GitStructure instance based on the given arguments.
fn new #
fn new(args_ GitStructureArgsNew) !&GitStructure
Retrieve or create a new GitStructure instance with the given configuration.
fn reset #
fn reset()
struct GetRepoUrlArgs #
struct GetRepoUrlArgs {
pub mut:
with_branch bool // // If true, return the repo URL for an exact branch.
}
struct GitCloneArgs #
struct GitCloneArgs {
pub mut:
url string
sshkey string
}
struct GitLocation #
struct GitLocation {
pub mut:
provider string // Git provider (e.g., GitHub)
account string // Account name
name string // Repository name
branch_or_tag string // Branch name
path string // Path in the repository (not the filesystem)
anker string // Position in a file
}
GitLocation uniquely identifies a Git repository, its online URL, and its location in the filesystem.
fn (GitLocation) patho #
fn (mut l GitLocation) patho() !pathlib.Path
Return a crystallib path object on the filesystem pointing to the locator
struct GitRepo #
struct GitRepo {
pub mut:
gs &GitStructure @[skip; str: skip] // Reference to the parent GitStructure
provider string // e.g., github.com, shortened to 'github'
account string // Git account name
name string // Repository name
status_remote GitRepoStatusRemote // Remote repository status
status_local GitRepoStatusLocal // Local repository status
status_wanted GitRepoStatusWanted // what is the status we want?
config GitRepoConfig // Repository-specific configuration
last_load int // Epoch timestamp of the last load from reality
deploysshkey string // to use with git
}
GitRepo holds information about a single Git repository.
fn (GitRepo) branch_create #
fn (mut repo GitRepo) branch_create(branchname string) !
Create a new branch in the repository.
fn (GitRepo) branch_switch #
fn (mut repo GitRepo) branch_switch(branchname string) !
fn (GitRepo) checkout #
fn (mut repo GitRepo) checkout() !
Checkout a branch in the repository.
fn (GitRepo) commit #
fn (mut repo GitRepo) commit(msg string) !
Commit the staged changes with the provided commit message.
fn (GitRepo) delete #
fn (mut repo GitRepo) delete() !
Deletes the Git repository
fn (GitRepo) display_current_status #
fn (mut repo GitRepo) display_current_status() !
fn (GitRepo) get_changes_staged #
fn (repo GitRepo) get_changes_staged() ![]string
Retrieves a list of staged changes in the repository.
This function returns a list of files that are staged and ready to be committed.
Returns:- An array of strings representing file paths of staged changes.
- Throws an error if the command execution fails.
fn (GitRepo) get_changes_unstaged #
fn (repo GitRepo) get_changes_unstaged() ![]string
Retrieves a list of unstaged changes in the repository.
This function returns a list of files that are modified or untracked.
Returns:- An array of strings representing file paths of unstaged changes.
- Throws an error if the command execution fails.
fn (GitRepo) get_last_local_commit #
fn (repo GitRepo) get_last_local_commit() !string
get commit for branch, will return '' if local branch doesn't exist remotely
fn (GitRepo) get_last_remote_commit #
fn (repo GitRepo) get_last_remote_commit() !string
is always the commit for the branch as known remotely, if not known will return ""
fn (GitRepo) get_parent_dir #
fn (repo GitRepo) get_parent_dir(args GetParentDir) !string
fn (GitRepo) get_path #
fn (repo GitRepo) get_path() !string
fn (GitRepo) get_path_of_url #
fn (repo GitRepo) get_path_of_url(url string) !string
gets the path of a given url within a repo ex: 'https://git.ourworld.tf/ourworld_holding/info_ourworld/src/branch/main/books/cocreation/SUMMARY.md' returns <repo_path>/books/cocreation/SUMMARY.md
fn (GitRepo) get_relative_path #
fn (repo GitRepo) get_relative_path() !string
Relative path inside the gitstructure, pointing to the repo
fn (GitRepo) gitlocation_from_path #
fn (mut gs GitRepo) gitlocation_from_path(path string) !GitLocation
Create GitLocation from the path within the Git repository
fn (GitRepo) has_changes #
fn (mut repo GitRepo) has_changes() !bool
Check if there are any unstaged or untracked changes in the repository.
fn (GitRepo) init #
fn (mut repo GitRepo) init() !
Check if repo path exists and validate fields
fn (GitRepo) need_commit #
fn (mut repo GitRepo) need_commit() !bool
Check if there are staged changes to commit.
fn (GitRepo) need_push_or_pull #
fn (mut repo GitRepo) need_push_or_pull() !bool
Check if the repository has changes that need to be pushed.
fn (GitRepo) open_vscode #
fn (repo GitRepo) open_vscode() !
Opens Visual Studio Code for the repo
fn (GitRepo) patho #
fn (repo GitRepo) patho() !pathlib.Path
Return rich path object from our library crystal lib
fn (GitRepo) pull #
fn (mut repo GitRepo) pull(args_ PullCheckoutArgs) !
Pull remote content into the repository.
fn (GitRepo) push #
fn (mut repo GitRepo) push() !
Push local changes to the remote repository.
fn (GitRepo) remove_changes #
fn (mut repo GitRepo) remove_changes() !
Removes all changes from the repo; be cautious
fn (GitRepo) reset #
fn (mut repo GitRepo) reset() !
alias for remove changes
fn (GitRepo) sourcetree #
fn (repo GitRepo) sourcetree() !
Opens SourceTree for the Git repo
fn (GitRepo) status_update #
fn (mut repo GitRepo) status_update(args StatusUpdateArgs) !
fn (GitRepo) tag_create #
fn (mut repo GitRepo) tag_create(tagname string) !
Create a new branch in the repository.
fn (GitRepo) tag_exists #
fn (mut repo GitRepo) tag_exists(tag string) !bool
Create a new branch in the repository.
fn (GitRepo) tag_switch #
fn (mut repo GitRepo) tag_switch(tagname string) !
struct GitRepoConfig #
struct GitRepoConfig {
pub mut:
remote_check_period int = 3600 * 24 * 3 // Seconds to wait between remote checks (0 = check every time), default 3 days
}
GitRepoConfig holds repository-specific configuration options.
struct GitRepoStatusLocal #
struct GitRepoStatusLocal {
pub mut:
branches map[string]string // Branch name -> commit hash
branch string // the current branch
tag string // If the local branch is not set, the tag may be set
}
GitRepoStatusLocal holds local status information for a repository.
struct GitRepoStatusRemote #
struct GitRepoStatusRemote {
pub mut:
ref_default string // is the default branch hash
branches map[string]string // Branch name -> commit hash
tags map[string]string // Tag name -> commit hash
}
GitRepoStatusRemote holds remote status information for a repository.
struct GitRepoStatusWanted #
struct GitRepoStatusWanted {
pub mut:
branch string
tag string
url string // Remote repository URL, is basically the one we want
readonly bool // if read only then we cannot push or commit, all changes will be reset when doing pull
}
this is the status we want, we need to work towards off
struct GitStructure #
struct GitStructure {
pub mut:
key string // Unique key representing the git structure (default is hash of $home/code).
config GitStructureConfig // Configuration settings for the git structure.
coderoot pathlib.Path // Root directory where repositories are located.
repos map[string]&GitRepo // Map of repositories, keyed by their unique names.
loaded bool // Indicates if the repositories have been loaded into memory.
}
GitStructure holds information about repositories within a specific code root. This structure keeps track of loaded repositories, their configurations, and their status.
fn (GitStructure) cachereset #
fn (mut gitstructure GitStructure) cachereset() !
Resets the cache for the current Git structure, removing cached data from Redis.
fn (GitStructure) clone #
fn (mut gitstructure GitStructure) clone(args GitCloneArgs) !&GitRepo
Clones a new repository into the git structure based on the provided arguments.
fn (GitStructure) do #
fn (mut gs GitStructure) do(args_ ReposActionsArgs) !string
do group actions on repo args
cmd string // clone,commit,pull,push,delete,reload,list,edit,sourcetree,cd
filter string // if used will only show the repo's which have the filter string inside
repo string
account string
provider string
msg string
url string
pull bool
script bool = true // run non interactive
reset bool = true // means we will lose changes (only relevant for clone, pull)
fn (GitStructure) get_repo #
fn (mut gitstructure GitStructure) get_repo(args_ ReposGetArgs) !&GitRepo
Retrieves a single repository based on the provided arguments. if pull will force a pull, if it can't will be error, if reset will remove the changes If the repository does not exist, it will clone it
Args:
ReposGetArgs {
filter string // Optional filter for repository names
name string // Specific repository name to retrieve.
account string // Git account associated with the repository.
provider string // Git provider (e.g., GitHub).
pull bool // Pull the last changes.
reset bool // Reset the changes.
reload bool // Reload the repo into redis cache
url string // Repository URL, used if cloning is needed.
Returns:- &GitRepo: Reference to the retrieved or cloned repository.
Raises:- Error: If multiple repositories are found with similar names or if cloning fails.
fn (GitStructure) get_repos #
fn (mut gitstructure GitStructure) get_repos(args_ ReposGetArgs) ![]&GitRepo
Retrieves a list of repositories from the git structure that match the provided arguments. if pull will force a pull, if it can't will be error, if reset will remove the changes
Args:
ReposGetArgs {
filter string // Optional filter for repository names
name string // Specific repository name to retrieve.
account string // Git account associated with the repository.
provider string // Git provider (e.g., GitHub).
pull bool // Pull the last changes.
reset bool // Reset the changes.
reload bool // Reload the repo into redis cache
url string // Repository URL, used if cloning is needed.
Returns:- []&GitRepo: A list of repository references that match the criteria.
fn (GitStructure) get_working_repo #
fn (mut gitstructure GitStructure) get_working_repo() ?GitRepo
returns the git repository of the working directory by locating the parent directory with .git
.
Returns:- GitRepo: Reference to the initialized repository.
Raises:- None: If .git
is not found in the parent directories.
fn (GitStructure) gitlocation_from_path #
fn (mut gs GitStructure) gitlocation_from_path(path string) !GitLocation
Get GitLocation from a path within the Git repository
fn (GitStructure) gitlocation_from_url #
fn (mut gs GitStructure) gitlocation_from_url(url string) !GitLocation
Get GitLocation from a URL
fn (GitStructure) init #
fn (mut gitstructure GitStructure) init() !
just some initialization mechanism
fn (GitStructure) load #
fn (mut gitstructure GitStructure) load(args StatusUpdateArgs) !
Loads all repository information from the filesystem and updates from remote if necessary. Use the reload argument to force reloading from the disk.
Args:- args (StatusUpdateArgs): Arguments controlling the reload behavior.
fn (GitStructure) repo_new_from_gitlocation #
fn (mut gitstructure GitStructure) repo_new_from_gitlocation(git_location GitLocation) !&GitRepo
just some initialization mechanism
fn (GitStructure) repos_print #
fn (mut gitstructure GitStructure) repos_print(args ReposGetArgs) !
Print repositories based on the provided criteria, showing their statuses
struct GitStructureArgGet #
struct GitStructureArgGet {
pub mut:
coderoot string
reload bool
}
struct GitStructureArgsNew #
struct GitStructureArgsNew {
pub mut:
coderoot string
light bool = true // If true, clones only the last history for all branches (clone with only 1 level deep)
log bool = true // If true, logs git commands/statements
debug bool = true
ssh_key_name string // name of ssh key to be used when loading the gitstructure
reload bool
}
struct GitStructureConfig #
struct GitStructureConfig {
pub mut:
coderoot string
light bool = true // If true, clones only the last history for all branches (clone with only 1 level deep)
log bool = true // If true, logs git commands/statements
debug bool = true
ssh_key_name string
}
struct PullCheckoutArgs #
struct PullCheckoutArgs {
pub mut:
submodules bool // if we want to pull for submodules
}
struct RepoInitParams #
struct RepoInitParams {
ssh_key_name string // name of ssh key to be used in repo
}
struct ReposActionsArgs #
struct ReposActionsArgs {
pub mut:
cmd string // clone,commit,pull,push,delete,reload,list,edit,sourcetree
filter string // if used will only show the repo's which have the filter string inside
repo string
account string
provider string
msg string
url string
branch string
recursive bool
pull bool
script bool = true // run non interactive
reset bool = true // means we will lose changes (only relevant for clone, pull)
}
struct ReposGetArgs #
struct ReposGetArgs {
pub mut:
filter string // Optional filter for repository names
name string // Specific repository name to retrieve.
account string // Git account associated with the repository.
provider string // Git provider (e.g., GitHub).
pull bool // Pull the last changes.
reset bool // Reset the changes.
reload bool // Reload the repo into redis cache
url string // Repository URL
}
ReposGetArgs defines arguments to retrieve repositories from the git structure. It includes filters by name, account, provider, and an option to clone a missing repo.
struct StatusUpdateArgs #
struct StatusUpdateArgs {
reload bool
ssh_key_name string // name of ssh key to be used when loading
}
- README
- Constants
- fn cachereset
- fn configreset
- fn get
- fn new
- fn reset
- struct GetRepoUrlArgs
- struct GitCloneArgs
- struct GitLocation
- struct GitRepo
- fn branch_create
- fn branch_switch
- fn checkout
- fn commit
- fn delete
- fn display_current_status
- fn get_changes_staged
- fn get_changes_unstaged
- fn get_last_local_commit
- fn get_last_remote_commit
- fn get_parent_dir
- fn get_path
- fn get_path_of_url
- fn get_relative_path
- fn gitlocation_from_path
- fn has_changes
- fn init
- fn need_commit
- fn need_push_or_pull
- fn open_vscode
- fn patho
- fn pull
- fn push
- fn remove_changes
- fn reset
- fn sourcetree
- fn status_update
- fn tag_create
- fn tag_exists
- fn tag_switch
- struct GitRepoConfig
- struct GitRepoStatusLocal
- struct GitRepoStatusRemote
- struct GitRepoStatusWanted
- struct GitStructure
- struct GitStructureArgGet
- struct GitStructureArgsNew
- struct GitStructureConfig
- struct PullCheckoutArgs
- struct RepoInitParams
- struct ReposActionsArgs
- struct ReposGetArgs
- struct StatusUpdateArgs