Being dangerous with git

keep calm and git rebase

By your geek friend:

Gediminas Morkevičius / @l3pp4rd

Who is this dude?

  • PHP, C, Go - programming language fanatic
  • open-source geek, Arch linux, DWM, ViM user
  • Author of Doctrine2 Extensions
  • And I share my stuff in github
Me

Why You should consider using git

  • git is decentralized
  • git is small and fast
  • git does not store changes - it stores snapshots
  • git has a staging area
  • git is a new standard?

When to use rebase or merge

Use rebase to cleanup, prepare and keep up to date your topic branches.

merge rebased topic branches or hotfixes

How to prevent THIS from happening?

git log --pretty=oneline --abbrev-commit
ugly commits

rebase your feature branches

Example:

mkdir ~/project && cd ~/project
git init
touch LICENSE
git add LICENSE
git commit -am 'initial commit - set license'
git remote add origin https://github.com/user/project.git
git checkout -b feature/project-bootstrap

After a while...

usual commits

Do you want this to go into master production stream?

Lets rebase

Interactively rebase 5 commits from HEAD

git rebase --interactive HEAD~5
rebase
manage commits in rebase

At this point we can choose what to do with commits. Rebase will rewind the chosen number of commits and modify them accordingly to prefered changes.

Initially rebase will stop to rename the first commit, we rename it properly:

rename first commit

Next, rebase will stop on "boostrap project" wich will have two commits squashed

squashed commits

Now if we had pushed our commits to git repository in any branch name, we could reference these commits with their hashes. This way it could look like:

Squash sample with references

Since we haven't, we can just leave those as extra commit messages

squashed commit message

Finally, it will stop to rename "add feature x" commit, it is not clear what feature we have added, lets fix it as well:

Rename add feature commit

When we save and close it, rebase will finish

And instead of...

usual commits

We have:

nice looking commits

Which history log do you choose to see in production?

Before merging it back to master - make sure you are up to date

git fetch
git rebase origin/master

There are cases, when you may want to split a commit, consider a situation:

Need to split

So what we should do ? - rebase!

git rebase -i HEAD~4

Set edit for commit, which we want to split

Edit commit to split during rebase

Rebase will rewind, pick the commit for edit and pause. Now lets reset one commit from the current HEAD

Rebase stops to edit
git reset HEAD~

Lets see what we have in staging area:

git status
Staging area status

Add the first commit, which includes doctrine2 orm. We will use git add --patch so we stage only a specific change.

git add --patch composer.json
Add using patch

Hit e to edit hunk

Add hunk

Now save and close it. We should have only needed changes staged.

git commit -m 'include doctrine2 orm into project'

Next, we have a front controller integration:

git add src/MyApp/FrontController.php public/*
git commit -m 'create front controller'

Further more, lets commit phpunit

git add phpunit.xml.dist tests

And again patch a composer.json change:

git add -p composer.json

Hit e to edit hunk

Add hunk for phpunit

Now save and close it. We should have only needed changes staged.

git commit -m 'bootstrap phpunit tests'

And finally we have only behat stuff left.

git add features composer.json
git commit -m 'bootstrap behat mink functional tests'
git rebase --continue

Thats it! Now we have:

Commits after split rebase

Have fun and be hardcore! And ...

keep calm and git rebase

Do not be afraid of rebase, experiment on your branches, keep branch backups if needed.