Skip to content
keyboard

A new development environment, a new git setup 💻

You have done this many times. You get a new laptop or desktop PC, you fiddle around a bit and then you start to set up your developer setup. And one of the things you install (if not already present) is git. With the install you also take the time and configure git. And I bet you never really care much for this. Me neither, until I started to look up the benefits. I just got a new laptop again, but this time I set aside time to check what benefits a proper config brings. Quickly I realized how useful this can be not only setting up name and email.

Now I won't go and explain every configuration option, but rather the ones that help me with daily work. And I am still improving the configuration as time goes by. Every time I read a blog post or stumble upon a new or newly discovered value, I try to apply it by finding a use case. If you want to explore all available configuration options, check out the official Git documentation on configuration.

Let's start with some settings that improve how you view and organize information in git.

Auto sort 🔢

Currently I set the "branch" and "tag" configuration to have an easier way to order them to my liking, and column.ui to fit them easily within the terminal window with as little scrolling as possible.

git config --global column.ui auto
git config --global branch.sort -committerdate
git config --global tag.sort version:refname

The idea is to use sorting by newest commit date for branches. That allows me to easily pick the newest or rather the latest branch people are working on. And then we have listing tags. There I prefer using "proper" ordering. As you have already experienced with any sorting by name, the numbers don't get "properly" sorted if you check the example below. By setting the sort value, you will be able to easily spot the newest tag.

$ git tag
nightly/0.5.100
nightly/0.5.1000
nightly/0.5.1001
nightly/0.5.101
nightly/0.5.1010

Now that we've covered how to organize existing branches and tags, let's look at how to set up new repositories properly from the start.

Default branch 🌿

You can define what the default branch should be when calling git init. That way you start with a default branch called "main" or the old "master" if you prefer.

git config --global init.defaultBranch main

With the basics of repository setup covered, let's move on to one of the most important areas: understanding and managing differences in your code.

Resolving differences 🔍

When reviewing changes or resolving conflicts, git's diff output is your primary tool. There are several configuration values you can set to make this easier and more informative.

Algorithm for comparing

Currently you can choose between 4 algorithms:

  • myers, which is the default
  • minimal
  • patience
  • histogram
git config --global diff.algorithm histogram

I personally use the histogram, and I would encourage you to use it as well, since I dare to say it is easier to understand.

Algorithm "Myers"

Dinosaur* getDinosaur(char* name)
 {
-  char* dataURL = getResource("dinosaurs", name);
-
-  if (dataURL != NULL)
+  if (name == NULL)
   {
-    return createDinosaur(dataURL);
+      log.error("Dinosaur name is null!");
+      return NULL;
   }
-  else
+
+  char* dataURL = getResource("dinosaurs", name);
+
+  if (dataURL == NULL)
   {
     fprintf(stderr, "Couldn't find data: %s", name);
+    return NULL;
   }
-  return NULL;
+  else
+    return createDinosaur(dataURL);
 }

Algorithm "Histogram"

Dinosaur* getDinosaur(char* name)
 {
+  if (name == NULL)
+  {
+      log.error("Dinosaur name is null!");
+      return NULL;
+  }
+
   char* dataURL = getResource("dinosaurs", name);

-  if (dataURL != NULL)
-  {
-    return createDinosaur(dataURL);
-  }
-  else
+  if (dataURL == NULL)
   {
     fprintf(stderr, "Couldn't find data: %s", name);
+    return NULL;
   }
-  return NULL;
+  else
+    return createDinosaur(dataURL);
 }

Color coding change 🎨

There is also the option to color highlight code that is moved or added as a new line. You can also highlight if a file was just renamed. I am sure you have double or triple checked some commit files only to find out the file was just renamed.

git config --global diff.colorMoved plain
git config --global diff.renames true

These diff improvements make code reviews and conflict resolution much clearer. Now let's tackle some common frustrations with daily git operations.

Eliminating repetitive tasks ⚡

One of the most annoying aspects of working with git is the repetitive nature of certain commands. Let's look at configurations that automate these tasks.

Setting upstream

I bet you always end up setting the upstream for every new branch you create. And this is pretty annoying if you ask me. Well fear not, there is a way to automatically set it, instead of git complaining like this:

$ git push
fatal: The current branch my-branch-name has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin my-branch-name

To avoid doing this, git can automatically do this for you. Just set the configuration as follows:

git config --global push.default simple
git config --global push.autoSetupRemote true

Autocorrecting typos ✨

Another thing that happens quite often to me is mistyping the git command. There is the option to let git autocorrect your command.

git config --global help.autocorrect prompt

The default is to not do this at all. I prefer git to guess and prompt me as shown above. This looks as follows:

git cmmit -m "Change color"

WARNING: You called a Git command named 'cmmit', which does not exist. Run 'commit' instead [y/N]?

These automation settings save time on everyday tasks. Beyond eliminating repetition, there are also configurations that help maintain a cleaner, more professional repository.

Keeping your repository clean 🧹

A well-maintained repository is easier to work with and understand. Here are some configurations that help with that.

Rebase on pull

By default, git pull performs a merge (it's equivalent to git fetch followed by git merge). This can create unnecessary merge commits in your history. Some engineers prefer to rebase instead, which replays your local commits on top of the fetched changes, keeping a cleaner, linear history.

git config --global pull.rebase true

With this setting, git pull will automatically rebase your local commits instead of merging. This is equivalent to running git fetch followed by git rebase manually. The result is a cleaner commit history without merge commits when pulling changes from remote.

Prune on fetch

Over time, your local repository can accumulate references to remote branches that no longer exist. This setting automatically cleans them up whenever you fetch.

git config --global fetch.prune true

This keeps your local repository clean by removing remote-tracking references that have been deleted on the remote. No more stale branches cluttering your git branch -r output.

Streamlining authentication 🔐

When working with remote repositories, you'll frequently need to authenticate. Rather than typing credentials repeatedly, you can configure git to handle this automatically.

Credential helper

Tired of entering your credentials repeatedly when pushing or pulling? The credential helper securely stores your credentials so you don't have to type them every time, when using HTTP.

The basic option works on all platforms and caches credentials in memory for 15 minutes by default:

git config --global credential.helper cache

However, each operating system has better platform-specific options:

macOS: Use osxkeychain to store credentials permanently in your system keychain:

git config --global credential.helper osxkeychain

Windows: Use manager (or manager-core for newer Git versions) for integration with Windows Credential Manager:

git config --global credential.helper manager

Linux: You have several options:

  • Use cache with a longer timeout (e.g., 1 hour = 3600 seconds):
    git config --global credential.helper 'cache --timeout=3600'
  • Use store to save credentials in a plain text file (less secure, but persistent):
    git config --global credential.helper store
  • Use a third-party credential manager like libsecret for GNOME Keyring integration, or integrate with password managers like Bitwarden or 1Password if they provide git credential helper support.

Personalizing your workflow 🎯

Finally, let's look at how you can customize git to match your personal working style.

Git aliases

Git aliases are custom shortcuts for commands you use frequently. They can save you significant typing and make your workflow more efficient.

git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.cm commit
git config --global alias.last 'log -1 HEAD'
git config --global alias.unstage 'reset HEAD --'
git config --global alias.amend 'commit --amend --no-edit'
git config --global alias.uncommit 'reset --soft HEAD^'

After setting these up, you can use git st instead of git status, git co instead of git checkout, and so on. You can also create more complex aliases for commands you use often. For example, a pretty log format:

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

Aliases are perhaps the most personal configuration setting—they evolve with your workflow and can dramatically reduce the keystrokes needed for your most common operations.

What's next? 🚀

I am still not a power user; there are plenty of other configurations I haven't seen yet or found a reason to use. But I am sure that some examples from the blog will save you time. And you should also not forget the fact that git is still being actively worked on. Therefore you never know what else will see the light of day and how it can ease your pain when working with git.

Were you even aware how convenient this configuration can be? If so, what are your configurations? Something I did not mention? 💭

Published by...

Image of the author

Jernej Klancic

Visit author page