Monday, July 02, 2012

Git (multiple repos)

Improving my Git workflow has been one of my current targets lately... Especially when working with multiple projects.

So, although I'm working all the time inside Eclipse, I still like to use the command line for many things (so, even with the Aptana Studio 3 Git integration and EGit having improved, I still use the command line a lot on common operations, resorting to other options mostly when investigating the history of a repository or some other thing which may be suboptimal in the command line).

To improve that situation, I ended up creating a tool... Yes, I know there are probably many other command line tools that try to accomplish that, but I did a good amount of research and didn't find anything that worked as I wanted -- and not nearly as fun (but I appreciate suggestions in this realm).

The tool I did is hosted at GitHub: https://github.com/fabioz/mu-repo, and it's freely available (GPL 3).

It's a Python program which interfaces with the git binary to execute whatever is needed. Also, for diffing operations it currently relies on WinMerge (meaning this part of the tool is Windows only for now, but if there's interest, it should be straightforward having it support other diff tools such as KDiff3).

My basic workflow is now:

cd /workspace (which has many .git subrepos)

Note: all the "mu" operations below will actually be applied to all the git subdirs (must be previously registered), so, a single command line is enough for dealing with all repositories at once -- yes, I know about git submodules, but I don't really like how it works -- and it's one of the main reasons this tool exists :)

To get changes:

mu up (fetches origin for the current branch updating the origin/current_branch reference -- I found it weird that trying to do "git fetch origin current_branch" ended up updating FETCH_HEAD instead of origin/current_branch -- also, this and most other operations work only in the current branch, leaving other branches or references untouched).

mu dd origin/current_branch (preview incoming changes: compare current branch HEAD to origin/current_branch).

mu rebase origin/current_branch (rebase incoming changes -- could also be: mu merge origin/current_branch).

To submit changes:

mu st (check status of changed files -- indexed or not)
mu dd (diff working copy with winmerge while editing changes and keeping the working dir updated even if no symlink support is available)
mu acp "message" (add all working copy changes, commit, push)

To start working on a feature:

mu co -b branch_name (create branch for all repos)
mu ac "message"  (add / commit changes on that branch)
mu co main_branch (go back to main branch)
mu rebase branch_name (get the changes from the branch into the main branch)
mu branch -D branch_name (remove that local branch)



Note that for my workflow I work mostly without taking "advantage" of the git index -- usually I review things with "mu dd" and on "mu ac" I add all the changes to the index and commit in a single operation (before that I was almost always doing "git add -A" and "git commit -m "message"" anyways).

I also still configure many things as I posted previously: http://pydev.blogspot.com.br/2011/02/git-on-command-line.html, but a bunch of things are now better integrated with this tool :)

Also, the tool works for a directory that has a '.git' repository, so, operations such as the diff with WinMerge can be used even when working with a single git repository.

p.s.: The tool is still in beta, so, although I'm using it all the time, it's possible that some things are not working as they should -- but on the good side, I still haven't been able to corrupt any of my git repos :)