Skip to content

Instantly share code, notes, and snippets.

@jyore
Last active November 10, 2015 09:09
Show Gist options
  • Save jyore/ff86e67f0db1f8bccd2f to your computer and use it in GitHub Desktop.
Save jyore/ff86e67f0db1f8bccd2f to your computer and use it in GitHub Desktop.
Useful Git Config commands

Useful Git Config Commands

This is a little doc I put together to help remember how to get back to my desired git config. It also has some useful commands that I have picked up from lessons learned in dealing with large development teams and managing lots of pull requests.

Hope this will help others as well

Setup Username/Email

Will simply setup the username and email address to publish commits under. Use the --global flag if you want to use the same information by default for all projects.

git config user.name <username>
git config user.email <email>

Push Strategy

My favorite is to use current, which Setup push current branch only AND will automatically create upstream branches if they do not exist! Requires Git 2.0+

git config --global push.default current

Password Cache

If you are in a situation where SSH keys are not feasible and you must use password access, you are probably beyond fed-up with typing your password in consistently. Good news is that you can setup a password cache within Git to keep you from having to constantly type it in. You basically just give the command below the time (in seconds) that you want to cache your credentials. I typically use 10hr or 36000s, this way, I type it in once per day, usually when I get into work in the morning.

git config credential.helper 'cache --timeout=<time-in-seconds>'

ReReRe (Reuse Recorded Resolution)

This command assists the developer in this process by recording conflicted automerge results and corresponding hand resolve results on the initial manual merge, and applying previously recorded hand resolutions to their corresponding automerge results. Enable it by:

git config --global rerere.enabled true

Force <LF> Line Ending

In environments where developers are working on all different types of base operating systems, you are probably driving yourself nuts with pull requests where the diffs are 90% line endings differences. The following commands will force <LF> line endings and not <CRLF>. You can always override per repo by running the commands w/o the --global flag.

git config --global core.autocrlf false
git config --global core.eol lf

Pomerge

For you java/maven guys:

This allows for versions in pom files to not get overwritten when syncing between branches on different version numbers. Add the following to your gitconfig

[merge "pommerge"] 
    name = A custom merge driver for Maven's pom.xml 
    driver = mergepom.py %O %A %B

Then,

cp $download-dir/mergepom.py <somewhere-in-execution-path>

you will need python installed, of course. This will run automagically when merging. Script attached

#! /usr/bin/env python
# Copyright 2013 Ralf Thielow <ralf.thielow@gmail.com>
# Licensed under the GNU GPL version 2.
import sys, subprocess, shlex, codecs
import xml.dom.minidom as dom
def change_version(old_version, new_version, cont):
return cont.replace("<version>"+old_version+"</version>",
"<version>" + new_version + "</version>")
def get_project_version(f):
try:
tree = dom.parse(f)
version = None
parent_version = None
for entry in tree.documentElement.childNodes:
if entry.nodeName == "version":
version = entry.firstChild.data
if entry.nodeName == "parent":
for entry2 in entry.childNodes:
if entry2.nodeName == 'version':
parent_version = entry2.firstChild.data
if version is not None:
# version has a priority over parent version
return version
else:
# may return None
return parent_version
except:
print(sys.argv[0] + ': error while parsing pom.xml')
return None
if len(sys.argv) < 4 or len(sys.argv) > 5:
print("Wrong number of arguments.")
sys.exit(-1)
ancestor_version = get_project_version(sys.argv[1])
current_branch_version = get_project_version(sys.argv[2])
other_branch_version = get_project_version(sys.argv[3])
# change current version in order to avoid merge conflicts
if (
current_branch_version is not None
and other_branch_version is not None
and ancestor_version is not None
and current_branch_version != other_branch_version
and other_branch_version != ancestor_version
):
with codecs.open(sys.argv[2], 'r', 'utf-8') as f:
other = f.read()
other = change_version(current_branch_version, other_branch_version, other)
with codecs.open(sys.argv[2], 'w', 'utf-8') as f:
f.write(other)
cmd = "git merge-file -p -L mine -L base -L theirs " + sys.argv[2] + " " + sys.argv[1] + " " + sys.argv[3]
p = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE)
git_merge_res = p.communicate()[0]
ret = p.returncode
git_merge_res_str = git_merge_res.strip().decode('utf-8')
cmd2 = "git rev-parse --abbrev-ref HEAD"
p2 = subprocess.check_output(shlex.split(cmd2))
branch = p2.strip().decode('utf-8')
cmd3 = "git config --get --bool merge.pommerge.keepmasterversion"
p3 = subprocess.Popen(shlex.split(cmd3), stdout=subprocess.PIPE)
val = p3.communicate()[0]
val = val.strip().decode('utf-8')
keep = False
if (p3.returncode == 0 and val == 'true'):
keep = True
# revert pom project version on current branch, unless in master. Allows for gitflow release-finish, hotfix-finish, and feature-finish to work better
if (current_branch_version is not None and (keep or branch != 'master')):
print('Merging pom version ' + other_branch_version + ' into ' + branch + '. Keeping version ' + current_branch_version)
git_merge_res_str = change_version(other_branch_version, current_branch_version, git_merge_res_str)
with codecs.open(sys.argv[2], 'w', 'utf-8') as f:
f.write(git_merge_res_str)
sys.exit(ret)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment