...
This commit is contained in:
@@ -2,112 +2,202 @@
|
||||
|
||||
This module provides Rhai wrappers for the Git functionality in SAL.
|
||||
|
||||
## Basic Git Operations
|
||||
> **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.
|
||||
|
||||
### Clone a Repository
|
||||
## 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
|
||||
// Clone a repository to a standardized location in the user's home directory
|
||||
let repo_path = git_clone("https://github.com/username/repo.git");
|
||||
print(`Repository cloned to: ${repo_path}`);
|
||||
// Create a new GitTree with a base path
|
||||
let git_tree = gittree_new("/root/code");
|
||||
print(`Created GitTree with base path: /home/user/code`);
|
||||
```
|
||||
|
||||
### List Repositories
|
||||
## Finding Repositories
|
||||
|
||||
### List All Repositories
|
||||
|
||||
```rhai
|
||||
// List all git repositories in the user's ~/code directory
|
||||
let repos = git_list();
|
||||
print("Found repositories:");
|
||||
// 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
|
||||
### Find Repositories Matching a Pattern
|
||||
|
||||
```rhai
|
||||
// Find repositories matching a pattern
|
||||
// Use a wildcard (*) suffix to find multiple matches
|
||||
let matching_repos = find_matching_repos("my-project*");
|
||||
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 = find_matching_repos("unique-project")[0];
|
||||
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_path = "/path/to/repo";
|
||||
if git_has_changes(repo_path) {
|
||||
let repo = git_tree.get("my-project")[0];
|
||||
if repo.has_changes() {
|
||||
print("Repository has uncommitted changes");
|
||||
} else {
|
||||
print("Repository is clean");
|
||||
}
|
||||
```
|
||||
|
||||
## Repository Updates
|
||||
## Repository Operations
|
||||
|
||||
### Update a Repository
|
||||
### Pull Changes
|
||||
|
||||
```rhai
|
||||
// Update a repository by pulling the latest changes
|
||||
// Pull the latest changes from the remote
|
||||
// This will fail if there are uncommitted changes
|
||||
let result = git_update("my-project");
|
||||
print(result);
|
||||
let repo = git_tree.get("my-project")[0];
|
||||
let result = repo.pull();
|
||||
print("Repository updated successfully");
|
||||
```
|
||||
|
||||
### Force Update a Repository
|
||||
### Reset Local Changes
|
||||
|
||||
```rhai
|
||||
// Force update a repository by discarding local changes and pulling the latest changes
|
||||
let result = git_update_force("my-project");
|
||||
print(result);
|
||||
// Reset any local changes in the repository
|
||||
let repo = git_tree.get("my-project")[0];
|
||||
let result = repo.reset();
|
||||
print("Repository reset successfully");
|
||||
```
|
||||
|
||||
### Commit and Update
|
||||
### Commit Changes
|
||||
|
||||
```rhai
|
||||
// Commit changes in a repository and then update it by pulling the latest changes
|
||||
let result = git_update_commit("my-project", "Fix bug in login form");
|
||||
print(result);
|
||||
// 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");
|
||||
```
|
||||
|
||||
### Commit and Push
|
||||
### Push Changes
|
||||
|
||||
```rhai
|
||||
// Commit changes in a repository and push them to the remote
|
||||
let result = git_update_commit_push("my-project", "Add new feature");
|
||||
print(result);
|
||||
// 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 repo_url = "https://github.com/username/example-repo.git";
|
||||
let repo_path = git_clone(repo_url);
|
||||
print(`Cloned repository to: ${repo_path}`);
|
||||
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 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 commit_message = "Update README.md";
|
||||
let result = git_update_commit_push(repo_path, commit_message);
|
||||
print(result);
|
||||
let result = repo.commit("Update README.md").push();
|
||||
print("Changes committed and pushed successfully");
|
||||
|
||||
// List all repositories
|
||||
let repos = git_list();
|
||||
let all_repos = git_tree.list();
|
||||
print("All repositories:");
|
||||
for repo in repos {
|
||||
print(` - ${repo}`);
|
||||
}
|
||||
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
|
||||
|
Reference in New Issue
Block a user