# Git Module for Rhai This module provides Rhai wrappers for the Git functionality in SAL. > **Note:** The constructor for GitTree has been renamed from `new()` to `gittree_new()` to avoid confusion with other constructors. This makes the interface more explicit and less likely to cause naming conflicts. ## Object-Oriented Design The Git module follows an object-oriented design with two main classes: 1. **GitTree** - Represents a collection of git repositories under a base path - Created with `gittree_new(base_path)` - Methods for listing, finding, and getting repositories 2. **GitRepo** - Represents a single git repository - Obtained from GitTree's `get()` method - Methods for common git operations: pull, reset, push, commit This design allows for a more intuitive and flexible interface, with method chaining for complex operations. ## Creating a GitTree The GitTree object is the main entry point for git operations. It represents a collection of git repositories under a base path. ```rhai // Create a new GitTree with a base path let git_tree = gittree_new("/root/code"); print(`Created GitTree with base path: /home/user/code`); ``` ## Finding Repositories ### List All Repositories ```rhai // List all git repositories under the base path let repos = git_tree.list(); print(`Found ${repos.len()} repositories`); // Print the repositories for repo in repos { print(` - ${repo}`); } ``` ### Find Repositories Matching a Pattern ```rhai // Find repositories matching a pattern // Use a wildcard (*) suffix to find multiple matches let matching_repos = git_tree.find("my-project*"); print("Matching repositories:"); for repo in matching_repos { print(` - ${repo}`); } // Find a specific repository (must match exactly one) let specific_repo = git_tree.find("unique-project")[0]; print(`Found specific repository: ${specific_repo}`); ``` ## Working with Repositories ### Get Repository Objects ```rhai // Get GitRepo objects for repositories matching a pattern let repos = git_tree.get("my-project*"); print(`Found ${repos.len()} repositories`); // Get a specific repository let repo = git_tree.get("unique-project")[0]; print(`Working with repository: ${repo.path()}`); ``` ### Clone a Repository ```rhai // Clone a repository by URL // This will clone the repository to the base path of the GitTree let repos = git_tree.get("https://github.com/username/repo.git"); let repo = repos[0]; print(`Repository cloned to: ${repo.path()}`); ``` ### Check for Changes ```rhai // Check if a repository has uncommitted changes let repo = git_tree.get("my-project")[0]; if repo.has_changes() { print("Repository has uncommitted changes"); } else { print("Repository is clean"); } ``` ## Repository Operations ### Pull Changes ```rhai // Pull the latest changes from the remote // This will fail if there are uncommitted changes let repo = git_tree.get("my-project")[0]; let result = repo.pull(); print("Repository updated successfully"); ``` ### Reset Local Changes ```rhai // Reset any local changes in the repository let repo = git_tree.get("my-project")[0]; let result = repo.reset(); print("Repository reset successfully"); ``` ### Commit Changes ```rhai // Commit changes in the repository let repo = git_tree.get("my-project")[0]; let result = repo.commit("Fix bug in login form"); print("Changes committed successfully"); ``` ### Push Changes ```rhai // Push changes to the remote let repo = git_tree.get("my-project")[0]; let result = repo.push(); print("Changes pushed successfully"); ``` ## Method Chaining The GitRepo methods can be chained together for more complex operations: ```rhai // Commit changes and push them to the remote let repo = git_tree.get("my-project")[0]; let result = repo.commit("Add new feature").push(); print("Changes committed and pushed successfully"); // Reset local changes, pull the latest changes, and commit new changes let repo = git_tree.get("my-project")[0]; let result = repo.reset().pull().commit("Update dependencies"); print("Repository updated successfully"); ``` ## Complete Example ```rhai // Create a new GitTree let home_dir = env("HOME"); let git_tree = gittree_new(`${home_dir}/code`); // Clone a repository let repos = git_tree.get("https://github.com/username/example-repo.git"); let repo = repos[0]; print(`Cloned repository to: ${repo.path()}`); // Make some changes (using OS module functions) let file_path = `${repo.path()}/README.md`; let content = "# Example Repository\n\nThis is an example repository."; write_file(file_path, content); // Commit and push the changes let result = repo.commit("Update README.md").push(); print("Changes committed and pushed successfully"); // List all repositories let all_repos = git_tree.list(); print("All repositories:"); for repo_path in all_repos { print(` - ${repo_path}`); } ``` ## Error Handling All methods in the Git module return a Result type, which means they can either succeed or fail with an error. If an error occurs, it will be propagated to the Rhai script as a runtime error. For example, if you try to clone a repository that doesn't exist: ```rhai // Try to clone a non-existent repository try { let git_tree = gittree_new("/root/code"); let repos = git_tree.get("https://github.com/nonexistent/repo.git"); print("This will not be executed if the repository doesn't exist"); } catch(err) { print(`Error: ${err}`); // Will print the error message from git } ``` Common errors include: - Invalid URL - Repository not found - Authentication failure - Network issues - Local changes exist when trying to pull