grit: Files | Directories

Command grit

Grit copies commits from a source repository to a destination repository. It is intended to mirror projects residing in an private monorepo to an external project-specific Git repository.


grit [-push] [-dump] [-linearize] src dst rules...

"grit -push src dst rules..." copies commits from the repository src to the repository dst, applying the the given rules and, if successful, pushes the changes to the destination repository. Repositories are named by url, prefix, and branch, with one of the following syntaxes:


The default prefix is "" and the default branch is "master". When a prefix is specified, Grit considers constructs a view of the repository limited to the given prefix path. Changes outside of this prefix are discarded.


If the flag -linearize is provided, then the source repository's history is linearized before copying commits. Linearization is done by ensuring that every commit has a single parent, so that the repository contains no merge commits. This is useful to ensure that grit can cleanly apply patches from repositories whose histories are not linear (e.g., when accepting patches from GitHub).


Grit can apply a set of rewrite rules to source commits before they are copied to the destination repository. Rules are specified as "kind:param". Rules kinds are:

  Strips diffs applied to files matching the given regular

  Strips commit messages when all files with changes match the given
  regular expression. This rule can be used to push internal cross-repo
  maintenance changes that do not need a context in the external world. For
  example, go.mod and go.sum files.

  Strip the commit named by the given hash. This is useful for excluding
  troublesome commits that you know are safe to ignore.

  For each file whose path matches regexp, regexp-replace each line in the
  file from old_re to new_re. For example, rule

rewrite:go.mod$:/replace .* => .*//
  will remove all "replace from => to" directives from go.mod
  files.  The 2nd letter after the path regexp ('/' in the example)
  determines the separator character for the old and the new regexps. The
  previous example can also be written as

rewrite:go.mod$:!replace .* => .*!!

One way sync

Copy commits from the "project/" directory in repository ssh:// to the root directory in the repository Diffs applied to files named BUILD are skipped.

grit -push ssh://,project/ \ "strip:^BUILD$" "strip:/BUILD$"

Two-way sync

Assume we want to sync bidirectionally between two repositories:


We usually develop on repoA and mirror changes to repoB. We also want to accept external contributions or upstream changes from repoB and push them to repoA. To sync from repoA to repoB, do the following:

grit -push $repoA $repoB

To sync from repoB to repo A, do the following:

# Pull changes from repoB to repoA. But don't push it automatically, since we want to
# review them internally.
grit $repoB $repoA
# grailXXXXX is the copy of repoA managed by grit
cd /var/tmp/grailXXXXX
# Squash changes into one
git reset --soft origin/master && git commit --edit -m"$(git log --reverse HEAD..HEAD@{1})"
# Start a regular code review process.
arc diff
# After the review is accepted, land the changes.
arc land

Package Files



gitPackage git implements support for querying and patching git repositories.

Package main imports 8 packages (graph). Updated 2019-10-29. Refresh now. Tools for package owners.