git-multi(1) ============ NAME ---- git-multi - execute the same git command in multiple repositories VERSION ------- This is `v<%= Git::Multi::VERSION %>` of 'git multi' ... hooray! SYNOPSIS -------- There are some options for `git multi` itself, in which case it is invoked as follows: [verse] 'git multi' [] To execute the same git command in multiple repositories, the invocation is as follows: [verse] 'git multi' [] DESCRIPTION ----------- Convenient way to execute the same git command in a set of related repos, currently the repositories of a GitHub user, incl. the organizations they are a member of; the repo list is determined via a GitHub API v3 call, and cached locally '(in binary format)' for performance and offline usage. OPTIONS ------- --help:: you're looking at it: show the man page --html:: open the HTML version of the man page --check:: checks all the required settings and configurations --version:: print out this script's version number --refresh:: refresh the list of user & organization repos --json:: output repository details to JSON --count:: print out the count of repos (per type) --list:: print out the names of all repos --archived:: print out the names of all repos --forked:: print out the names of all repos --private:: print out the names of all repos --paths:: print out the full path for each repos --spurious:: list cloned repos whose remote doesn't match a github.com origin --missing:: print out names of repos that haven't been cloned --stale:: list repos that have been deleted on github.com --excess:: list repos that don't exist on github.com --clone:: clones missing repositories into `${HOME}/Workarea` (by default) --query (args):: query GitHub repo metadata for each repository --find :: print out the repos for which the Ruby code evaluates to true --eval :: execute the given Ruby code in the context of each repo --raw :: execute the given shell command inside each git repository EXAMPLES -------- count the number of repos git multi --list | wc -l disk usage of each locally cloned repo git multi --paths | xargs -n 1 du -hs disk usage using the `--raw` option git multi --raw 'du -hs .' group and count the repos by GitHub-determined language git multi --query language | cut -f 2 -d : | sort | uniq -c | sort -n -r find out the most-used Ruby versions git multi --raw '[ -f .ruby-version ] && cat .ruby-version' | cut -f 2 -d : | sort | uniq -c | sort -n -r find GitHub repos without a description git multi --query description | egrep ': *$' fetch remote branches for all repos git multi fetch -p print out the local branch for each repo git multi rev-parse --abbrev-ref=strict HEAD find all repos for which the 'origin' remote isn't github.com git multi config --get remote.origin.url | fgrep -v git@github.com: a kind of "repository creation" report: count the number of repos created in each quarter git multi --eval "class ::Time; def quarter() (month.to_f / 3.0).ceil; end; end; puts format('%d-Q%d', created_at.year, created_at.quarter)" | sort | uniq -c for each repo, list all remote branches, sorted by the "age" of the last commit on each branch git multi for-each-ref --sort="-authordate" --format="%(refname)%09%(authordate:relative)%09%(authorname)" refs/remotes/origin same as above, but columnize the generated output (NOTE: replace '^I' with CTRL-V/CTRL-I in your terminal) git multi for-each-ref --sort="-authordate" --format="%(refname)%09%(authordate:relative)%09%(authorname)" refs/remotes/origin | column -t -s "^I" same as above, but refresh the list of remote branches first git multi fetch -p ; git multi for-each-ref --sort="-authordate" --format="%(refname)%09%(authordate:relative)%09%(authorname)" refs/remotes/origin find all Rails projects git multi --raw '[ -f Gemfile ] && fgrep -q -l rails Gemfile && echo uses Rails' | cat find all Mongoid dependencies git multi --raw '[ -f Gemfile.lock ] && egrep -i "^ mongoid (.*)" Gemfile.lock' | column -s: -t find all projects that have been pushed to in the last week git multi --find '((Time.now - pushed_at) / 60 / 60 / 24) <= 7' print out the number of days since the last push to each repository git multi --eval 'puts "%d days" % ((Time.now - pushed_at) / 60 / 60 / 24)' find all projects that have seen activity this calendar year git multi --find 'pushed_at >= Date.civil(Date.today.year, 1, 1).to_time' print out all webhooks git multi --eval '(hooks = client.hooks(project.full_name)).any? && begin print project.full_name ; print "\t" ; puts hooks.map { |hook| ["", hook.name, hook.config.url].join("\t") } ; end' print out all deploy keys git multi --eval '(keys = client.list_deploy_keys(project.full_name)).any? && begin print project.full_name ; print "\t" ; puts keys.map(&:title).sort.join("\t") ; end' find all organization repositories that depend on a given org repo, e.g. 'business_rules' git multi --graph | fgrep business_rules generate a dependency graph of all organization repositories using yuml.me DEPENDENCIES=$( git multi --graph | ruby -n -e 'parent, children = $_.split(": ") ; puts children.split(" ").map { |child| "[#{parent}]->[#{child}]" }' | tr '\n' ',' ) ; open "http://yuml.me/diagram/scruffy/class/${DEPENDENCIES}" generate a dependency graph of all organization repositories using Graphviz git multi --graph | ruby -n -e 'parent, children = $_.split(": ") ; puts children.split(" ").map { |child| "\"#{parent}\"->\"#{child}\";" }' | awk 'BEGIN { print "digraph {\nrankdir=\"LR\";\n" } ; { print ; } END { print "}\n" } ; ' | dot -Tpng > /tmp/ghor.png ; open -a Preview /tmp/ghor.png QUERY ARGUMENTS --------------- The following is a list of valid arguments for the `git multi --query` option: <%= Git::Hub::query_args %> JQ INTEGRATION -------------- `jq` is like `sed` for JSON data... all of the above query arguments can be used in conjunction with `jq` to query, filter, map and transform the GitHub repository attributes stored in the local, binary repository cache; here are some examples: # print out each repository's name and its description git multi --json | jq '.[] | .name + ": " + .description' # print out the name of all "forked" repositories git multi --json | jq '.[] | select(.fork == true) | .full_name' FILES ----- `${HOME}/Workarea`:: root directory where repos will been cloned `${HOME}/.git/multi/repositories.byte`:: local, binary cache of GitHub repository metadata REFERENCES ---------- * homepage for `git-multi`: https://github.com/pvdb/git-multi * the GitHub API: https://developer.github.com/v3/ * the `jq` command-line utility: http://stedolan.github.io/jq/