GIT-META(1) Git Extensions GIT-META(1) NAME git-multi -- execute the same git command in multiple repositories SYNOPSIS git multi DESCRIPTION Convenient way to execute the same git command in a set of related repos, currently the list of an organization's repositories on Github. Said list is determined via a Github API v3 call, and cached locally for performance. OPTIONS git multi --help # you're looking at it git multi --check # checks all the required settings and configurations git multi --version # print out this script's version number git multi --refresh # refresh the list of organization repos git multi --json # output repository details to JSON git multi --count # print out the count of organization repos (per type) git multi --list # print out the names of all organization repos git multi --archived # print out the names of all organization repos git multi --forked # print out the names of all organization repos git multi --private # print out the names of all organization repos git multi --paths # print out the full path for each organization repos git multi --spurious # list cloned repos whose remote doesn't match a github.com origin git multi --missing # print out names of repos that haven't been cloned git multi --stale # list repos that have been deleted on github.com git multi --excess # list repos that don't exist on github.com git multi --clone # clones missing repositories into "${HOME}/Workarea" (by default) git multi --query (args) # query Github repo multidata for each repository git multi --find # print out the repos for which the Ruby code evaluates to true git multi --eval # execute the given Ruby code in the context of each repo get multi --raw # execute the given shell command inside each git repository EXAMPLES # count the number of organization repos git multi --list | wc -l # disk usage of each locally cloned organization repo git multi --paths | xargs -n 1 du -hs # ... or by 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 organization 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 organization repositories that depend on a given org repo, e.g. 'business_rules' git multi --graph | fgrep business_rules # 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' # 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 %{query_args} USE `jq` TO QUERY THE `git multi` CACHE `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 `${HOME}/.gitmulti.byte` 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 organization repos have been cloned REFERENCES # the Github API call used to refresh the list of organization repos http://developer.github.com/v3/orgs/teams/#list-team-repos # the `jq` command-line utility http://stedolan.github.io/jq/ git-multi %{version} 1 March 2015 GIT-META(1)