diff --git a/CLAUDE.md b/CLAUDE.md index eb4f2e0..0b50952 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -23,9 +23,11 @@ The entire implementation is a single Babashka script (`commitly`) with these ke - `has-changes?` - Uses `git status --porcelain` to detect uncommitted changes - `commit-changes` - Executes `git add -A` and `git commit -m` for a repo - `push-changes` - Executes `git push` for a repo +- `pull-changes` - Executes `git pull` for a repo - `status-all` - Shows git status for all modified repositories - `commitly` - Main orchestration function that coordinates commit workflow - `push-all` - Pushes all repositories without committing +- `pull-all` - Pulls changes for all repositories - `-main` - CLI argument parsing and entry point ### Workflow @@ -54,6 +56,9 @@ commitly push "commit message" # Push only (no commit) - useful after manual commits commitly push + +# Pull changes for all subrepos +commitly pull ``` ### Running via Babashka Tasks diff --git a/README.md b/README.md index df713a5..3838930 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ A CLI tool for making commits to many subrepos after a distributed change. - Automatically detects which subrepos have uncommitted changes - Creates commits with a single message across all modified subrepos - Push changes to remote repositories after committing +- Pull changes from remote repositories across all subrepos - View status of all modified repositories - Reports commit status for each subrepo - Written in Babashka for fast startup and easy distribution @@ -31,6 +32,9 @@ commitly push "Your commit message here" # Push only (without committing) commitly push + +# Pull changes for all subrepos +commitly pull ``` ## Requirements @@ -82,8 +86,9 @@ ln -s $(pwd)/commitly ~/.local/bin/commitly 3. Depending on the command: - `status`: Shows git status for all modified repositories - ``: Commits changes in each modified repository with the provided message - - `-p `: Commits and pushes changes to remote - - `-p` (no message): Pushes all repositories without committing + - `push `: Commits and pushes changes to remote + - `push` (no message): Pushes all repositories without committing + - `pull`: Pulls changes from remote for all repositories 4. Reports success/failure for each repository ## Use Case diff --git a/commitly b/commitly index 37795b8..e3cb8d4 100755 --- a/commitly +++ b/commitly @@ -62,6 +62,20 @@ (catch Exception e {:success false :repo repo-path :error (.getMessage e)}))) +(defn pull-changes [repo-path] + "Pull changes from remote repository" + (try + (let [pull-result (process/shell {:dir repo-path + :out :string + :err :string + :continue true} + "git pull")] + (if (zero? (:exit pull-result)) + {:success true :repo repo-path} + {:success false :repo repo-path :error (:err pull-result)})) + (catch Exception e + {:success false :repo repo-path :error (.getMessage e)}))) + (defn show-status [repo-path] "Show git status for a repository" (let [result (process/shell {:dir (str repo-path) @@ -146,6 +160,27 @@ (println (format "\n%d repositories failed to push" (count failed))) (System/exit 1)))))) +(defn pull-all [] + "Pull changes for all repositories" + (let [repos (find-subrepos (fs/cwd)) + pull-results (map pull-changes repos) + successful (filter :success pull-results) + failed (filter #(not (:success %)) pull-results)] + + ;; Report successes + (doseq [result successful] + (println (format "✓ %s" (fs/file-name (:repo result))))) + + ;; Report failures + (when (seq failed) + (println (format "\n%d repositories failed to pull:" (count failed))) + (doseq [result failed] + (println (format "✗ %s" (fs/file-name (:repo result)))) + (println (format " Error: %s" (:error result)))) + (System/exit 1)) + + (println (format "\nSuccessfully pulled %d repositories." (count successful))))) + ;; CLI entry point (defn -main [& args] (if (empty? args) @@ -153,11 +188,13 @@ (println "Usage: commitly ") (println " commitly status") (println " commitly push []") + (println " commitly pull") (println "") (println "Commands:") (println " status Show git status for all subrepos with changes") (println " push Push all repositories without committing") (println " push Commit and push changes across all modified subrepos") + (println " pull Pull changes for all repositories") (println " Commit changes across all modified subrepos (no push)") (System/exit 1)) (let [first-arg (first args) @@ -167,6 +204,10 @@ (= "status" first-arg) (status-all) + ;; Pull command + (= "pull" first-arg) + (pull-all) + ;; Push command (= "push" first-arg) (if (empty? rest-args) diff --git a/skills/commitly/commitly.md b/skills/commitly/commitly.md index f5ae76f..6c704a9 100644 --- a/skills/commitly/commitly.md +++ b/skills/commitly/commitly.md @@ -23,6 +23,7 @@ This installs `commitly` to `~/.local/bin/commitly` (ensure `~/.local/bin` is in commitly status # Show status of modified repos commitly # Commit changes (no push) commitly push [] # Push (and optionally commit) changes +commitly pull # Pull changes for all repos ``` ### Commands @@ -31,6 +32,7 @@ commitly push [] # Push (and optionally commit) changes - `` - Commit changes across all modified repositories (no push) - `push` - Push all repositories without committing - `push ` - Commit and push changes across all modified repositories +- `pull` - Pull changes from remote for all repositories ### Examples @@ -54,6 +56,11 @@ commitly push "feat: add new feature" commitly push ``` +**Pull changes for all repos:** +```bash +commitly pull +``` + ## How It Works 1. **Discovery**: Scans the current directory for subdirectories containing `.git` folders @@ -63,6 +70,7 @@ commitly push - ``: Runs `git add -A` and `git commit -m ""` for each modified repo (no push) - `push `: Commits and then runs `git push` for each successfully committed repo - `push` (no message): Runs `git push` for all repos without committing + - `pull`: Runs `git pull` for all repos ## When to Use