Development Workflow with Git, Part 2: Scripts and Tools to Facilitate the Workflow
Part 1 of this article described a standard development workflow using Git that took advantage of the distributed nature of the system to maintain a code base across two or three different repositories, including a primary shared "working" code repository and a development "work-in-progress" code repository. Some aspects of this workflow are tedious and reptititive, while others, such as the management of different branches in different repositories can make housekeeping a little more complex. In this, the second part of the two-part series, I present a few simple scripts or tools that, when incorporated into the development ecosystem, go such a long way in alleviating these problems that the whole process quickly becomes a seamless and natural part of the standard routine.
Note that any executable file with a name beginning with "git-" on your system path will automatically be picked up as a "git" subcommand. So by creating custom scripts that help your development workflow, and naming them "git-something", you can invoke them seamlessly as part of the Git "porcelain".
-
The whole business of creating and associating a development repository can be made easier through a tool such as YonderGit:
$ ygit.py setup dev remote.host.ip:repos/project-dev.git
- When pulling from a shared repository, it would be great to see in a glance what changes have been brought in. Adding the "
whatsnew" and "whatsnewlog" aliased commands will give you that. - The creation of feature branches for works-in-progress can be wrapped up with a script such as "
git-mkdev" (and invoked via "git mkdev"):#! /bin/sh
dev_remote_name='dev'
show_usage() {
echo Usage: git mkdev \<new-branch-name\>
echo
echo Creates new branch with current HEAD as ancestor,
echo and pushing branch to remote named \'${dev_remote_name}\'.
}
remotes=$(git remote)
if [[ -n $remotes ]]
then
dev_found=0
for remote in ${remotes[@]}
do
if [[ $remote == ${dev_remote_name} ]]
then
dev_found=1
if [[ -n $1 ]]
then
git checkout -b $1 && git push dev $1:$1 && exit
else
show_usage
fi
fi
done
if [[ $dev_found != 1 ]]
then
echo No remote named \'${dev_remote_name}\'.
fi
fi -
An enhanced log view, showing the symbolic references associated with each commit, will make it much easier to manage multiple branches across multiple remotes.
- The deleting of feature branches for merged or abandoned works-in-progress can be wrapped up with a script such as "
git-rmdev" (and invoked via "git rmdev"):#! /bin/sh
dev_remote_name='dev'
show_usage() {
echo Usage: git rmdev \<dev-branch-name\>
echo
echo Removes development branch \<dev-branch-name\> from both
echo local as well as remote repository \'${dev_remote_name}\'.
}
remotes=$(git remote)
if [[ -n $remotes ]]
then
dev_found=0
for remote in ${remotes[@]}
do
if [[ $remote == ${dev_remote_name} ]]
then
dev_found=1
if [[ -n $1 ]]
then
git branch -d $1 && git push dev :$1 && exit
else
show_usage
fi
fi
done
if [[ $dev_found != 1 ]]
then
echo No remote named \'${dev_remote_name}\'.
fi
fi - Pushing to multiple upstream repositories can be wrapped up wih a script such as "
git-pushall":#! /bin/sh
remotes=$(git remote)
if [[ -n $remotes ]]
then
for remote in $remotes;
do
cmd="git push $remote $@"
echo
echo "[$remote]: $cmd"
$cmd
done
fi
feed