{"id":37102648,"url":"https://github.com/mslinn/git_tree_go","last_synced_at":"2026-01-14T12:26:12.370Z","repository":{"id":318719558,"uuid":"1071823995","full_name":"mslinn/git_tree_go","owner":"mslinn","description":"This Go package installs commands that walk through one or more git directory trees (breadth-first) and act on each repository.","archived":false,"fork":false,"pushed_at":"2025-12-04T18:28:07.000Z","size":46378,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-12-08T02:06:06.753Z","etag":null,"topics":["git","golang"],"latest_commit_sha":null,"homepage":"https://mslinn.com/git/1100-git-tree.html","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mslinn.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-07T21:31:31.000Z","updated_at":"2025-12-04T18:28:13.000Z","dependencies_parsed_at":null,"dependency_job_id":"9f3162b1-eb8e-4dd8-9410-5f40dcee96c8","html_url":"https://github.com/mslinn/git_tree_go","commit_stats":null,"previous_names":["mslinn/git_tree_go"],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/mslinn/git_tree_go","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mslinn%2Fgit_tree_go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mslinn%2Fgit_tree_go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mslinn%2Fgit_tree_go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mslinn%2Fgit_tree_go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mslinn","download_url":"https://codeload.github.com/mslinn/git_tree_go/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mslinn%2Fgit_tree_go/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28420757,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T10:47:48.104Z","status":"ssl_error","status_checked_at":"2026-01-14T10:46:19.031Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["git","golang"],"created_at":"2026-01-14T12:26:11.632Z","updated_at":"2026-01-14T12:26:12.348Z","avatar_url":"https://github.com/mslinn.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# `git-tree-go` [![GitHub newest release](https://img.shields.io/github/v/release/mslinn/git_tree_go)](https://github.com/mslinn/git_tree_go/releases/latest)\n\n\nThis Go package installs commands that walk through one or more git\ndirectory trees (breadth-first) and act on each repository.\nDirectories containing a file called `.ignore` are ignored, as well as all subdirectories.\nMultiple goroutines are normally used to dramatically boost performance,\nbut serial processing is available for deterministic results.\n\n\n## Command Summary\n\n- The `git-commitAll` command commits and pushes all changes to each repository\n  in the tree. Repositories that are in a detached `HEAD` state are skipped.\n\n- The `git-evars` command writes a script that defines environment variables\n  pointing to each git repository.\n\n- The `git-exec` command executes an arbitrary shell command for each repository.\n\n- The `git-list-executables` command lists all the executables created by this package.\n\n- The `git-replicate` command writes a script that clones the repositories in the tree,\n  and adds any defined remotes.\n\n  - Any git repos that have already been cloned into the target directory tree\n    are skipped. This means you can rerun `git-replicate` as many times as you\n    want, without ill effects.\n\n  - All remotes in each repository are replicated.\n\n- The `git-update` command updates each repository in the trees.\n\n\n## Installation\n\n### Prerequisites\n\n[Install the Go language](https://go.dev/doc/install) if you need to.\n\nYou need Go 1.24 or later installed on your system.\n\n```shell\n$ go version\ngo version go1.24.2 linux/amd64\n```\n\n### Install Release\n\nTo install the command-line programs from releases on the GitHub repository\nwithout manually cloning, use `go install`.\n\nThe following provides the most recently released version:\n\n```shell\n$ go install github.com/mslinn/git_tree_go/cmd/...@latest\n```\n\nThe following provides version 0.1.9:\n\n```shell\n$ go install github.com/mslinn/git_tree_go/cmd/...@v0.1.9\n```\n\n\n### Building from Source\n\nDownload, build and install to `$HOME/go/bin/` like this:\n\n```shell\n$ git clone https://github.com/mslinn/git_tree_go.git\n$ cd git_tree_go\n$ make install\n```\n\n\n## Configuration\n\nThe `git-tree-go` commands can be configured to suit your preferences.\nConfiguration settings are resolved in the following order of precedence,\nwhere items higher in the list override those lower down:\n\n1. **Environment Variables**\n2. **User Configuration File** (`~/.treeconfig.yml`)\n3. **Default values** built into the program.\n\nThis allows for flexible customization of the program's behavior.\n\n\n### Interactive Setup: `git-treeconfig`\n\nThe easiest way to get started is to use the `git-treeconfig` command.\nThis interactive tool will ask you a few questions\nand create a configuration file for you at `~/.treeconfig.yml`.\n\nThis is the help message produced by `git-treeconfig -h`:\n\n```text\ngit-treeconfig - Configure git-tree settings\nThis utility creates a configuration file at $HOME/.treeconfig.yml\nPress Enter to accept the default value in brackets.\n\nUsage: git-treeconfig [OPTIONS]\n\nOPTIONS:\n  -h   Show this help message\n```\n\nLets use `git-treeconfig` now.\n\n```shell\n$ git-treeconfig\nWelcome to git-tree configuration.\nThis utility will help you create a configuration file at: /home/user/.treeconfig.yml\nPress Enter to accept the default value in brackets.\n\nGit command timeout in seconds? |300| 600\nDefault verbosity level (0=quiet, 1=normal, 2=verbose)? |1|\nDefault root directories (space-separated)? |sites sitesUbuntu work| dev projects\n\nConfiguration saved to /home/user/.treeconfig.yml\n```\n\n### Configuration File\n\nThe `git-treeconfig` command generates a YAML file (`~/.treeconfig.yml`) that you can also edit manually.\nNotice in this example that the roots start with a dollar sign ($):\n\n```yaml\n---\ngit_timeout: 600\nverbosity: 1\ndefault_roots:\n- $dev\n- $projects\n```\n\n**Note:** The `default_roots` entries can be:\n- **Environment variable names** (e.g., `sites`, `work`) - will be expanded automatically if the environment variable exists\n- **Environment variable references** (e.g., `$sites`, `$work`) - explicitly marked with `$` prefix\n- **Literal directory paths** (e.g., `/home/user/projects`, `./local-repos`) - used as-is\n\nIf an entry looks like a valid environment variable name (alphanumeric and underscores only) and that environment variable is defined, it will be automatically expanded. Otherwise, it will be treated as a literal directory path.\n\n### Environment Variables\n\nFor temporary overrides or use in CI/CD environments, you can use environment variables.\nThey must be prefixed with `GIT_TREE_` and be in uppercase.\n\n- `export GIT_TREE_GIT_TIMEOUT=900`\n- `export GIT_TREE_VERBOSITY=2`\n- `export GIT_TREE_DEFAULT_ROOTS=\"dev projects personal\"` (space-separated string)\n\n\n## Use Cases\n\n### Dependent Package Maintenance\n\nA directory tree holds Jekyll plugins, packaged as 25 gems.\nThey depend on one another, and must be built in a particular order.\nSometimes an operation must be performed on all of the plugins,\nand then all the gems must be rebuilt.\n\nMost operations do not require that the projects be processed in\nany particular order, however the build process must be invoked on the\nprimary dependencies first.\nIt is quite tedious to do this 25 times, over and over.\n\nThis use case is fulfilled by the `git-exec` command provided by the `git-tree-go` package.\nSee below for further details.\n\n\n### Replicating Trees of Git Repositories\n\nWhenever setting up an operating system for a new development computer,\none of the tedious tasks that must be performed is to replicate\none or more directory trees of Git repositories.\n\nIt is a bad idea to attempt to copy an entire Git repository between computers,\nbecause the `.git` directories within them can be quite large.\nSo large, in fact, that it might take much more time to copy than re-cloning.\n\nThe reason is that copying the entire Git repository actually means copying the same information twice:\nfirst the `.git` hidden directory, complete with all the history for the project,\nand then again for the files in the currently checked out branch.\nGit repos store the entire development history of the project in their `.git` directories,\nso as they accumulate history they eventually become much larger than the\ncode that is checked out at any given time.\n\nThis use case is fulfilled by the `git-replicate` and `git-evars`\ncommands provided by this package, working together.\n\n```text\n    ┌───────────────┐     ┌───────────────────────────┐\n    │  Old Computer │     │        New Computer       │\n    │ git-replicate │ ═══►│   git-evars\u003e$work/.evars  │\n    └───────────────┘     └───────────────────────────┘\n```\n\n`git-replicate` generates a script that recreates the same git directory trees\nin the new computer that are found in the old computer.\nIgnored subtrees of Git repositories are not processed.\n\nThe script generated by `git-replicate` is then copied to the new computer and run;\nthis recreates the Git repositories that are not ignored.\n`git-evars` is then used to generate the contents of the script that generates\nenvironment variable pointing to every Git repository in the new computer.\nThe diagram calls this script `$work/.evars`.\n\n## Usage\n\n### Single- And Multi-Processing\n\nAll of these commands are default to multi-processing mode using\n[goroutines](https://dev.to/gophers/what-are-goroutines-and-how-are-they-scheduled-2nj3).\nYou may notice that your computer's fan gets louder when you run these commands on large numbers of Git repositories.\n\nFor builds and other sequential tasks, however, multiprocessing is inappropriate.\nInstead, it is necessary to build components in the proper order.\nDoing all the work as a single process is a straightforward way of ensuring proper task ordering.\n\nUse the `-s/--serial` option when the order that Git projects are processed matters.\nAll of the commands support this option.\nExecution will take much longer than without the option,\nbecause performing most tasks take longer to perform in sequence than performing them via multiprocessing.\n\n### `git-commitAll`\n\nThis is the help message produced by `git-commitAll -h`:\n\n```text\ngit-commitAll - Recursively commits and pushes changes in all git repositories under the specified roots.\nIf no directories are given, uses default roots (sites, sitesUbuntu, work) as roots.\nSkips directories containing a .ignore file, and all subdirectories.\nRepositories in a detached HEAD state are skipped.\n\nOptions:\n  -h, --help              Show this help message and exit.\n  -m, --message MESSAGE   Use the given string as the commit message.\n                          (default: \"-\")\n  -q, --quiet             Suppress normal output, only show errors.\n  -s, --serial            Run tasks serially in a single thread in the order specified.\n  -v, --verbose           Increase verbosity. Can be used multiple times (e.g., -v, -vv).\n\nUsage:\n  git-commitAll [OPTIONS] [ROOTS...]\n\nUsage examples:\n  git-commitAll                      # Commit default repositories with the default message (\"-\")\n  git-commitAll -m \"Commit message\"  # Commit default repositories with the same message\n  git-commitAll $work $sites         # Commit in repositories under specific roots with the default message\n```\n\n```shell\n$ git-commitAll\nProcessing $sites $sitesUbuntu $work\n\nAll work is complete.\n```\n\n\n### `git-evars`\n\nThis is the help message produced by `git-evars -h`:\n\n```text\ngit-evars - Generate environment variable definitions for git repositories in directory trees.\n\nExamines trees of git repositories and generates a bash script that defines\nenvironment variables pointing to each git repository.\nIf no directories are given, default roots are used (sites, sitesUbuntu, work) as roots.\nThese environment variables point to roots of git repository trees to walk.\nSkips directories containing a .ignore file, and all subdirectories.\n\nDoes not redefine existing environment variables; messages are written to STDERR to indicate environment\nvariables that are not redefined.\n\nEnvironment variables that point to the roots of git repository trees must have been exported, for example:\n\n  $ export work=$HOME/work\n\nUsage: git-evars [OPTIONS] [ROOTS...]\n\nOptions:\n  -h, --help           Show this help message and exit.\n  -q, --quiet          Suppress normal output, only show errors.\n  -z, --zowee          Optimize variable definitions for size.\n  -v, --verbose        Increase verbosity. Can be used multiple times (e.g., -v, -vv).\n\nROOTS can be directory names or environment variable references enclosed within single quotes (e.g., '$work').\nThe environment variable reference must be contained within single quotes to prevent expansion by the shell.\nMultiple roots can be specified in a single quoted string.\n\nUsage examples:\n$ git-evars                 # Use default environment variables as roots\n$ git-evars '$work $sites'  # Use specific environment variables\n```\n\nThe following appends to any script in the `$work` directory called `.evars`.\nThe script defines environment variables that point to each git repository pointed to by `$work`:\n\n```shell\n$ git-evars '$work' \u003e\u003e $work/.evars\n$ source $work/.evars\n$ cd $snakesHaveMoreFun\n...\n$ cd $camels_get_it_done\n```\n\n\n#### Generated Script from `git-evars`\n\nFollowing is a sample of environment variable definitions.\nThe `-z`/`--zowee` option generates intermediate environment variable definitions,\nmaking them much easier to work with.\n\n```shell\n$ git-evars -z '$sites'\nexport mnt=/mnt\nexport c=$mnt/c\nexport _6of26=$sites/6of26\nexport computers=$sites/computers.mslinn.com\nexport ebooks=$sites/ebooks\n...\n```\n\n\n### `git-exec`\n\nThis is the help message produced by `git-exec -h`:\n\n```text\ngit-exec - Executes an arbitrary shell command for each repository.\n\nIf no arguments are given, uses default roots (sites, sitesUbuntu, work) as roots.\nThese environment variables point to roots of git repository trees to walk.\nSkips directories containing a .ignore file, and all subdirectories.\n\nEnvironment variables that point to the roots of git repository trees must have been exported, for example:\n\n  $ export work=$HOME/work\n\nUsage: git-exec [OPTIONS] [ROOTS...] SHELL_COMMAND\n\nOptions:\n  -h, --help           Show this help message and exit.\n  -q, --quiet          Suppress normal output, only show errors.\n  -s, --serial         Run tasks serially in a single thread in the order specified.\n  -v, --verbose        Increase verbosity. Can be used multiple times (e.g., -v, -vv).\n\nROOTS can be directory names or environment variable references (e.g., '$work').\nMultiple roots can be specified in a single quoted string.\n\nUsage examples:\n1) For all git repositories under $sites, display their root directories:\n  $ git-exec '$sites' pwd\n\n2) For all git repositories under the current directory and $my_plugins, list the demo/ subdirectory if it exists.\n  $ git-exec '. $my_plugins' 'if [ -d demo ]; then realpath demo; fi'\n\n3) For all subdirectories of the current directory, update Gemfile.lock and install a local copy of the gem:\n  $ git-exec . 'bundle update \u0026\u0026 rake install'\n```\n\n#### Example 1\n\nFor all subdirectories of current directory,\nupdate `Gemfile.lock` and install a local copy of the gem:\n\n```shell\n$ git-exec '$jekyll_plugins' 'bundle \u0026\u0026 bundle update \u0026\u0026 rake install'\n```\n\n#### Example 2\n\nList the projects under the directory pointed to by `$my_plugins`\nthat have a `demo/` subdirectory:\n\n```shell\n$ git-exec '$my_plugins' 'if [ -d demo ]; then realpath demo; fi'\n```\n\n\n### `git-list-executables`\n\nThis is the help message produced by `git-list-executables -h`:\n\n```text\ngit-list-executables - Lists executables installed by git-tree-go.\n\nUsage: git-list-executables [OPTIONS]\n\nOPTIONS:\n  -h, --help           Show this help message and exit.\n```\n\nExample:\n\n```shell\n$ git-list-executables\nExecutables installed by git-tree-go in: /mnt/f/work/git/git_tree_go/bin\n\ngit-commitAll: Commit all changes in the current repository.\ngit-evars: Lists all environment variables used by git.\ngit-exec: Execute a command in each repository of the tree.\ngit-list-executables: Lists executables installed by git-tree-go.\ngit-replicate: Replicate a git repository.\ngit-treeconfig: Manage the git-tree configuration.\ngit-update: Update all repositories in the tree.\n```\n\n\n### `git-replicate`\n\nThis is the help message produced by `git-replicate -h`:\n\n```text\ngit-replicate - Writes a bash script to STDOUT for replicating trees of Git repositories.\n\nIf no directories are given, uses default roots (sites, sitesUbuntu, work) as roots.\nThe script clones the repositories and replicates any remotes.\nSkips directories containing a .ignore file.\n\nOptions:\n  -h, --help           Show this help message and exit.\n  -q, --quiet          Suppress normal output, only show errors.\n  -v, --verbose        Increase verbosity. Can be used multiple times (e.g., -v, -vv).\n\nUsage: git-replicate [OPTIONS] [ROOTS...]\n\nROOTS can be directory names or environment variable references (e.g., '$work').\nMultiple roots can be specified in a single quoted string.\n\nUsage examples:\n$ git-replicate '$work'\n$ git-replicate '$work $sites'\n\nWhen `git-replicate` completes, edit the generated script to suit, then\ncopy it to the target machine and run it.\n```\n\n\n### `git-update`\n\nThis is the help message produced by `git-update -h`:\n\n```text\ngit-update - Recursively updates trees of git repositories by running git pull.\n\nIf no arguments are given, uses default roots (sites, sitesUbuntu, work) as roots.\nThese environment variables point to roots of git repository trees to walk.\nSkips directories containing a .ignore file, and all subdirectories.\n\nEnvironment variables that point to the roots of git repository trees must have been exported, for example:\n\n  $ export work=$HOME/work\n\nUsage: git-update [OPTIONS] [ROOTS...]\n\nOPTIONS:\n  -h, --help           Show this help message and exit.\n  -q, --quiet          Suppress normal output, only show errors.\n  -s, --serial         Run tasks serially in a single thread.\n  -v, --verbose        Increase verbosity. Can be used multiple times (e.g., -v, -vv).\n\nROOTS:\nWhen specifying roots, directory paths can be specified, and environment variables can be used, preceded by a dollar sign.\n\nUsage examples:\n\n$ git-update               # Use default environment variables as roots\n$ git-update $work $sites  # Use specific environment variables\n$ git-update $work /path/to/git/tree\n```\n\n**Note:** When environment variables are used as roots (e.g., `$work`), the output will display\npaths in condensed form using the variable name. For example, instead of showing\n`Updating /mnt/f/work/CanPolitique`, it will show `Updating $work/CanPolitique`.\n\n\n## Development\n\nSee [DEVELOPMENT.md](DEVELOPMENT.md).\n\n\n## License\n\nThe package is available as open source under the terms of the\n[MIT License](https://opensource.org/licenses/MIT).\n\n\n## Additional Information\n\nMore information is available on\n[Mike Slinn's website](https://www.mslinn.com/git/1100-git-tree.html)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmslinn%2Fgit_tree_go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmslinn%2Fgit_tree_go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmslinn%2Fgit_tree_go/lists"}