Lauri's notes

Git notes

Set Up Git

git config --global user.name "YOUR NAME"
git config --global user.email "YOUR EMAIL ADDRESS"

# To prevent accidental pushes to branches which you are not ready to push yet
git config --global push.default upstream

# push relevant annotated tags when pushing branches out
git config --global push.followTags true

# Setup rebase for every tracking branch
git config --global branch.autosetuprebase always

# Store HTTPS passwords permanently
git config --global credential.helper store
# ... or cache for an hour
git config --global credential.helper 'cache --timeout=3600'

# Do not conflict with compiled files specified in .gitattributes
git config --global merge.ours.driver true

# Fetch notes
git config --add remote.origin.fetch +refs/notes/*:refs/notes/*

Diffing image files

git config diff.exif.textconv exiv2
echo '*.png diff=exif' >> .gitattributes

Always fetch and push all tags

git config --add remote.origin.fetch '+refs/tags/*:refs/tags/*'
git config --add remote.origin.push '+refs/tags/*:refs/tags/*'

All notes: '+refs/notes/*:refs/notes/*' All branches (bad idea): '+refs/heads/*:refs/heads/*'

Setting the default git branch

git symbolic-ref HEAD refs/heads/mybranch    # on local
git remote set-head origin mybranch          # on remote

Branch descriptions

git branch --edit-description          # From 1.7.9
git config branch.topic.description

Detach subdirectory into separate Git repository

# existing-repo
# ├── Dir1
# ├── Dir2
# ├── Dir3
# └── something-more.text

git subtree split -P Dir2 -b new-branch
git remote add new-repo git@example.com:user/new-repo.git
git push new-repo new-branch:master

Clearing your history

# Remove one file/folder
git filter-branch --index-filter "git rm -rfq --cached --ignore-unmatch ABC" --prune-empty HEAD
# Remove all other files/folders
git filter-branch --index-filter "git ls-files | grep -v heating_cost | xargs -r git rm -rfq --cached" --prune-empty HEAD
git filter-branch -f --prune-empty --index-filter 'git rm --cached "*" ":!:*i18n.js"'
# Rename file
git filter-branch --tree-filter 'if [ -f old ]; then mkdir dir && mv old dir/new; fi' HEAD
# Remove tags from commit message
git filter-branch -f --msg-filter 'sed "s/^app: //"'

# Remove empty commits
git filter-branch --prune-empty HEAD

Random


# Oldest commit dates
git log --pretty=tformat:%ai $(git rev-list --max-parents=0 HEAD)

# Newest commit dates
git for-each-ref --sort='-authordate' --format='%(authordate:iso8601)' refs/heads

# Copyright years
git log --all --pretty=tformat:%ai | cut -d- -f1 | sort -u | sed '1b;$!d' | paste -s -d"-"

export GIT_COMMITTER_DATE="2015-03-25 15:41:03 +0200"
git commit --amend --date "2015-03-25 15:41:03 +0200" -m 'fix committer_date and author_date'
unset GIT_COMMITTER_DATE

$ git clone --no-hardlinks rules-yoga rules-temp
$ cd rules-temp
$ git remote rm origin
# Remove all exept ..
$ git filter-branch -f --prune-empty --index-filter "git rm --cached --ignore-unmatch $(git ls-files | grep -Ev 'keep1.txt|keep2.txt' | tr "\n" " ")"
# Remove one file
$ git filter-branch -f --prune-empty --index-filter "git rm -f --cached --ignore-unmatch unwanted.txt"
# Show changed files between two commit
$ git show --pretty="format:" --name-only 8cb536c..HEAD | sort -u

$ git filter-branch -f --parent-filter 'P="`git log --pretty=%P -n 1 $GIT_COMMIT` ";N=`git show-branch --independent $P|tr "\n" " "`;test "$P" = "$N" && cat || echo "-p $N"' 9a5c4bf2665..HEAD
$ git filter-branch -f --parent-filter 'git show-branch --independent `git log --pretty=%P -n 1 $GIT_COMMIT` | sed "s/^/-p /" | grep -v " "||cat' 9a5c4bf2665..HEAD

# another way
git clone --no-hardlinks rules-elion rules-temp
cd rules-temp/
git filter-branch --index-filter "git ls-files | grep -vf /home/lauri/code/yoga/rules.text | xargs -r git rm -rfq --cached" --prune-empty HEAD
git filter-branch -f --prune-empty HEAD
git checkout -b cleanup
git reset --hard <initial commit>
git cherry-pick --allow-empty ..master
# on fail
git cherry-pick --continue
git filter-branch -f --prune-empty HEAD
# on conflict, find merge commit that resolves conflict
# and take correct file from there
git checkout <merge-hash> file-in-conflict
git cherry-pick --continue

Tags: git

Have an update or suggestion for this note? You can edit it and send me a pull request.

Since 2009 to 2024