git-topic

git-topic is a git command to help with a particular kind of workflow, in which all work is written by an author, and reviewed by someone else.

Units of work are organized into topics. Conceptually topics are similar to git branches, except that they are namespaced, either in wip (work in progress), review or rejected.

Authors begin by _working\ on_ a topic. When they are done, they indicate the topic is ready for review. A reviewer then either accepts the topic (merges into master) or rejects the topic, usually with comments.

This is all fairly easy to do with policy, e.g. by indicating the state of a topic by the name of its branch. git-topic helps to automate one particular policy.

Requirements

  • git-topic has only been tested on debian flavours of linux. Other unix-like environments should work.

  • git >= 1.7.1 (older versions may work, sans comment commands)

  • ruby >= 1.9.2-rc1 (older versions may work)

Workflow

Workflow in brief

Doing Work

  1. Create a topic branch in the wip namespace.

  2. Do some work.

  3. Rebase to create a nice commit history.

  4. Push to the review namespace. If the wip branch was pushed (e.g. because you work on multiple machines) destroy it on the remote.

  5. Create a local branch from a rejected branch.

  6. Do some work, resolve the reviewer’s issues.

  7. go to step 3, above.

Reviewing

  1. Create a local branch from a review branch somebody else pushed.

  2. Review their work.

  3. either:

a.i::     Accept; merge (fast-forward) master
 ii::     Destroy the review branch. 
b::       Reject; add notes and push to the rejected namespace and remove from
          the review namespace.

Workflow with git-topic

Doing Work

# Work on a (possibly new, possibly rejected) topic
git topic work-on <topic>

# done with topic; push it for someone to review
git topic done [<topic>]

Reviewing

# see if we have any topics to review (or rejected topics to fix up)
git topic status

git topic review [<topic>]

# happy with the review, get it into master
git topic accept

# unhappy with the review
# edit files to add file-specific comments (see +git-topic+ +comment+
# +--help+ for details).

# save your file specific comments, and launch an editor to enter general
# comments about the topic.
git topic comment

# push the topic to rejected.
git topic reject

Again, but with aliases

# first install aliases
#   add --local if you don't want to update your global aliases
git topic install-aliases

# alternatively
git work-on <topic>

# see reviewer's comments
git comments

# finished, submit work
git done

# does status --prepend so you get git status output as well as git topic
# status
git st

# alternatively
#   git r <topic>
git review <topic>

git accept
# or
git comment
git reject

Commenting

Reviewer Comments

When initially rejecting a branch, the reviewer can, and should, write comments explaining why the branch was rejected. These fall into two categories: genera and line-specific comments. To make line-specific comments easier, the reviewer can add comments directly in source files before invoking git comment.

Each line of those annotations should begin with a pound sign. git comment will convert these comments into formatted plain text. Paragraphs are automatically formatted, but indented lines are left intact. So, for instance, editing foo.rb from

def foo
  x = initial_value_of_x
  x.change!
end

to

# This is an exciting name for a function, but I fear it is perhaps not as
# descriptive as it could be.  And this comment is a little long, but I
# think it's to make the point that source comments are automatically
# formatted.  In any case, how about
#
#    def a_much_better_function_name
#        excellent_implementation
#    end
# 
def foo
  x = initial_value_of_x
  x.change!
end

and then invoking git comment will format the above paragraph, annotated with git config user.name and wrapped, but leaving the indented lines unformatted.

The actual changes to foo.rb will then be discarded. git comment tries hard not to discard non-comment changes and will do nothing if any of the output of git diff reports lines that do not meet the above format.

After the diff comments have been applied, git comment will start an instance of your EDITOR so you can write general comments.

Responding to Comments

The author can view the reviewer’s comments with git comments, and reply with git comment. The latter will start an instance of their EDITOR, from which replies can be made inline.

Bash autocompletion

See git-topic --completion-help for details. In short, you have to do some manual work, because loading completions as a gem is too slow (see Misc, below, and ruby issue 3465).

  1. Make sure you source share/completion.bash __before__ sourcing git’s standard completion.

  2. Copy bin/git-topic-completion to your gem env’s default bin dir, overriding the generated git-topic-completion. Otherwise, autocompletion will be too slow to be useful.

  3. Alternatively, install git-topic with the --no-wrappers flag.

Misc

At present the binary is stupidly slow. Actually, the binary is not slow, but all rubygems binaries are slow. See ruby issue 3465. One way around this is to modify your PATH so you invoke the binary directly (instead of the rubygem wrapper). Alternatively, put up with a 300ms load time until you have a ruby with the issue fixed.

Note on Patches/Pull Requests

  1. Fork the project.

  2. Make your feature addition or bug fix.

  3. Add tests for it. This is important so I don’t break it in a future version unintentionally.

  4. Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)

  5. Send me a pull request. Bonus points for topic branches.

Copyright © 2010 David J. Hamilton. See LICENSE for details.

References

  1. redmine.ruby-lang.org/issues/show/3465