7.4.13

Turning micro-commits into one megacommit


When I first learned about versioning you were told to "commit often".  On larger open source projects I've been painfully learning that the story is a little different -- you want to squash the granularity of your commits so that there is a 1-1 commit-to-feature ratio.
So - you need to distill all your micro commits into a **single** mega commit. 

[update - attached a shell script to automate this at the bottom of this post]

First you need to know where "micro-commits" come from. 

Micro commits can come from (at least) two places.  In my case - they come from pulls, and from me.

1) The insidious micro-commit generator lurking within: git pull.
When you issue:

git pull

Git is actually doing TWO things for you:

- Pulling down source code from remote
- Merging it into your branch <-- this is a source of a commit :(

2) Another micro-commit source: you.
The other micro-commits are the ones you deliberately do:

git commit -m "another teenie-tiny commit with a single semicolon in it"

 
Now - you need to know how to squash them.

 There are two rules to commit squashing:
  • REBASE when you pull from remote ! This squashes your "pull" micro commits. 
  • When you push to the main branch (or issue pull requests to the main branch), you should do so by CREATING a specific new branch, merging commits from your "development" branch by using the "--squash" option. 
  • Note that you can automate rebasing in your .git/ config files.

Example 

 Say you have "my_feature_branch" that you want to merge into "master".   Here is what a workflow might look like.


#Do some work
git checkout my_feature_branch
touch a
git add a
git commit -m "micro commit 1" 

#Maybe you want to pull some stuff down ... heres the cleanest way to do it.
git pull origin master --rebase 
#okay... now lets do some MORE work...
touch b
git add b 
git commit -m "micro commit 2"

At this point, you have 2 commits (you would have 3 if you didn't do the rebase).

# Now... checkout the master branch, and merge all of micro commits into one mega commit.
git checkout master
git merge --squash my_feature_branch
git commit -m "a mega commit with 2 commits worth of new stuff, which is already also merged with latest master"

Update - here's a shell script that creates a new branch off of master and pulls your current branch's commits into it - without creating a new commit). 

#starting at the current branch
 

#1 Parse the current branch name
Current=`git branch | grep "*" | sed -e 's/*//' | sed -e 's/ //'`
Ext="_squashed"
Squashed=$Current$Ext
echo "New branch is $Squashed"

 
#2 Checkout master , we will branch off of it
git checkout master
echo "Now on master..."
git branch
 

#3 Checkout the squashed branch
git branch -t $Squashed
echo "Created branch : $Squashed"
 

#4 Checkout new branch
git checkout $Squashed
echo "New branch "
git branch
 

#5 Merge with the original work branch
git merge --squash $Current
echo "Final Branch"
git branch

No comments:

Post a Comment