Category Archives: Git

Using Gerrit for better collaboration on git projects

I’m working with a small team that is divided in two geographical locations. This separation has made collaboration a little challenging which has compromised the quality of the code base. I’m exploring tools that can help us collaborate better, particularly making it easy to review each others code.

Gerrit promises a platform that makes it possible to create ACLs on top of git repositories, so that code can’t be committed until an official approver checks and approves the code. Ideally, the workflow will look something like this:

  • Carlos makes changes and commits them to his local repository
  • Carlos pushes his changes to Gerrit and creates a code review
  • Luis, as an owner of the project reviews the code and suggests changes
  • Carlos makes the changes, commits them and updates the code review
  • Luis looks at the changes and approves them
  • Carlos can now push the changes to upstream

Read more »

Trunk development flow with git

The trunk development flow is an alternative to gitflow or github flow that is used at very big companies(LinkedIn, Google, FaceBook) to allow many developers to work in the same code base with the least amount of friction.

This model existed before git, so it doesn’t really use all its power. If you have done development using another flow, it might even feel wrong at the beginning, because it discourages branching and merging, but it is all for a good reason.

These are the rules I follow when using the trunk model with git:

  • Master is always stable – The master branch should always be stable and deployable. For this reason your codebase should be guarded by as many tests and monitoring as possible. Developers should feel comfortable deploying anything that goes to master as soon as it is committed because there may be a system that continuously deploys the master branch.
  • No merges allowed – The master branch should remain flat by always rebasing to it. Keeping the master branch flat makes is easier to bisect and revert commits.
  • No branches for large tasks – On other flows, branches are created for large tasks that may take days or weeks. This makes development easy, but integration hard. When you are done developing your feature and are ready to add your changes to master, there may be conflicts. Fixing conflicts that are weeks old is hard and error prone. To avoid this problem and still allow for large tasks, use feature toggles instead.

Git bisect

Git bisect helps you find out the commit that introduced a bug. It has happened a few times that somebody discovers a bug that I knew used to work fine before. When this happens I go back to an arbitrary point in the git history and try to reproduce the bug. If the bug is still present I go back a little more, until I find a point where the bug is not there. Then I try to find the commit that introduced the bug by searching through the commits between the commit I know works and the one I know doesn’t.

Git bisect helps you do this more efficiently by using a binary search. Lets say you are now in the HEAD of your master branch and you know there is a bug in there. You can start a bisect session by running:

1
2
git bisect start
git bisect bad

Read more »

Git rebasing vs merging

When I switched to git for the first time I had a very hard time understanding what rebasing did to a point where I totally avoided it. I had been doing all my work on private and public repositories by going to master and merging to my feature branch or to a team member’s branch. I was happy with this way of working until I started on my new job a few months ago and they had a rebase based workflow. It goes something like this:

1
2
3
4
5
6
cd repo
git pull --rebase
// Do some work and add stage it
git commit -m 'Some message'
git pull --rebase
git push origin master

In this little example I am working in my local master branch, but if I wanted I could create a feature branch and rebase it to master as needed. The most obvious benefit about this workflow is a very clean history. Lets look at a simple example of a merge based history:

Read more »

Changing your default name and e-mail on git

If you just installed git in your computer you probably got a message telling you that your name and e-mail haven’t been configured and suggesting you to change them the first time you commit:

1
2
3
git config --global user.name "First Last"
git config --global user.email email@domain.com
git commit --amend --reset-author

This will set “First Last” and email@domain.com as your default name and email for any git repository you work on in that computer. This may be something you don’t want because probably you want to have different identities in different computers. One thing you can do is amend your commits with an alternate identity you want to use:

1
git commit --amend --author="First Last <email@domain.com>"

If you will constantly be working on this repository this will become annoying really fast, so instead you can set your identity for a specific repository by adding this to your .git/config file:

1
2
3
[user]
  name = First Last
  email = email@domain.com

Working with Git submodules

Git submodules is a way to organize your code so you can include libraries or other projects into your project. You want to treat these libraries as a separate repository so they are by themselves versioned by git in another repository.

Lets start with a very simple, but not very practical example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Create a git repository
mkdir somedir
cd somedir
touch file
git add file
git commit -m 'Added file'

# Create another repository inside the current repository
mkdir submodule
cd submodule
touch submodule_file
git add submodule_file
git commit -m 'Added file'

# Add the child repository to the parent repository as a submodule
cd ..
git submodule add ./submodule/
git commit -m 'Added submodule'

Read more »

Colorize git output

In linux git doesn’t show colors by default. To make git diff, log, status, etc…, show pretty colors you need to issue this command from a terminal:

1
git config --global color.ui true

Pushing and deleting remote branches with git

Creating new branches and deleting them locally is an easy task with git, but when it comes to doing it for a remote repository, happily, it is very easy too.

Pushing a branch

If you have a new branch named mybranch on your local repository and you want to push it to a remote so other people can see it you can do:

1
git push remotename mybranch

Most of the time you will probably want to push to the origin remote, so the command will be something like this:

1
git push origin mybranch

Read more »

Creating and applying patches with git

Creating and applying patches using git is a task relatively easy to do. I will show how it all works using an example scenario.

Let’s say we have a main repository with just one commit on it:

1
2
adrian@laptop:~/repository$ git lg
* ff4c135 - (HEAD, master) first commit (2012-04-12 19:14:39 -0700) <juanito>

That repository has been copied by other people that are working on the same project. Now lets say that I am the one that cloned the main repository and did some work on it:

1
2
3
4
adrian@laptop:~/copy$ git lg
* be3ec44 - (HEAD, origin/master, origin/HEAD, master) Third commit (2012-04-12 19:16:28 -0700) <adrian>
* 1551977 - second commit (2012-04-12 19:16:00 -0700) </adrian><adrian>
* ff4c135 - first commit (2012-04-12 19:14:39 -0700) <juanito>

Read more »

Getting more from git log

This post is basically a copy of pimping out git log. I just made some modifications to Bart’s alias to fit my personal preferences.

This code creates an alias named lg for the git:

git config --global alias.lg "log --graph --pretty=format:'%Cred%h -%C(yellow)%d%Creset %s %Cgreen(%ci) %C(bold blue)<%an>'"

Here is an explanation of what that command does:

git config --global alias.lg "..."

Read more »