git-sync-all: Sync workflow
What git-sync-all does per repository: discovery, tags, commit with git add -A, pull, push, conflict detection, stash workflow, recovery and result states.
git-sync-all: Sync workflow
Finding repositories
The tool uses find to look for directories named .git down to depth SYNC_SCAN_DEPTH below each base directory. It then filters:
- Include filter: if
SYNC_INCLUDEis set, the directory name must match one pattern. - Exclude filter: if the directory name matches a pattern from
SYNC_EXCLUDE, the repository is skipped. - Remote check: a repository without a remote named
SYNC_REMOTEis skipped silently (visible only with-v).
Only real .git directories count. Worktrees and submodules, where .git is a file, are not found. Nested repositories are treated as repositories of their own.
Per-repository flow
graph TD
A[Repository] --> B[Fetch tags]
B --> C[Check state and fetch remote]
C --> D{Changes in working tree?}
D -->|yes| E[Commit decision]
D -->|no| F[Pull]
E --> F
F --> G[Push]
G --> H[Result clean, synced, skipped or failed]
1. Tags
If tags are enabled, the tool runs git fetch --tags --prune-tags <remote>. Errors are ignored. The tool never pushes tags.
--prune-tagsonly removes local tags that the remote does not know when Git pruning is enabled as well (fetch.prune=trueorremote.<name>.prune=truein your Git configuration). In that case locally created, not yet pushed tags are lost. Without such a setting the command only fetches new tags. With--no-tagsorSYNC_TAGS=falsethe step is skipped entirely.
2. Check state
A repository is "dirty" when git status --porcelain prints anything. That includes untracked files. Unless --no-pull is set, the tool runs git fetch <remote> <branch> for the current branch and compares HEAD with the upstream (@{u}). If the branch has no upstream there is nothing to pull and nothing to push as far as the tool is concerned.
3. Changes in the working tree
| Situation | Behaviour |
|---|---|
| Dirty, remote has no new commits | The tool shows up to 5 changed files and asks Commit and push changes? [y/n/q]. |
| Dirty and remote has new commits | The tool shows files and the number of new commits and lists files changed both locally and on the remote. Then the menu follows: c (commit), s (stash), k (skip), q (abort, see below). |
Dirty with --no-commit, remote has new commits |
Automatic stash, pull, stash pop. |
Dirty with --no-commit, remote unchanged |
No action. |
Dirty with --no-pull |
Same as "remote has no new commits": plain commit prompt. |
With --yes the prompt is skipped. When files overlap (changed locally and remotely), SYNC_CONFLICT_STRATEGY decides:
| Strategy | Effect in auto mode with overlapping files |
|---|---|
skip |
The repository is skipped and counted as Skipped. |
stash |
Stash, pull, stash pop. Changes stay uncommitted. |
commit |
Commit and then pull, even if conflicts may arise. |
Without overlapping files, auto mode always commits. Without a terminal and without --yes the repository is skipped.
If you answer q, the tool prints Aborted by user and ends only the handling of that repository. It counts as Failed, the remaining repositories are still processed, and the exit code is 1.
4. Commit
The commit consists of git add -A and git commit -m <message> -m <body>. git add -A stages all changes including untracked files, unless .gitignore excludes them. Commit hooks run as usual. Interactively you can override the message (Enter accepts the default). With --yes or without a terminal the template from SYNC_COMMIT_MSG is used.
5. Pull
If the upstream has new commits, the tool runs git pull --rebase <remote> <branch>, or git pull <remote> <branch> with SYNC_PULL_STRATEGY=merge. If the pull fails, the tool aborts a running rebase or merge itself (git rebase --abort or git merge --abort), prints the Git error indented and counts the repository as Failed. The repository stays in its state from before the pull.
6. Push
If the branch has commits ahead of the upstream, the tool runs git push <remote> <branch> without --force. If the push fails, the repository counts as Failed. The tool never switches branches and always works on the current one.
Stash workflow
git stash push --include-untracked, then pull, then git stash pop. If the pull fails, the stash is restored. If the pop has conflicts, the tool reports it and hints to resolve them and then run git stash drop. The repository then counts as Failed.
Results
| Result | Meaning |
|---|---|
Clean |
Nothing to do. |
Synced |
At least one action ran (commit, pull or push). |
Skipped |
You chose n or k, or there was no terminal and no --yes. |
Failed |
Commit, stash, pull or push failed, or you aborted with q. Leads to exit code 1. |
A failure in one repository does not stop the run. The remaining repositories are still processed.