Git tips & tricks collection
Common tricks in git and some helpful commands.
Push without –set-upstream
From Git 2.37.1+, you can now push branches without having to specify --set-upstream origin feature/xyz
when no upstream tracking exists f or the current branch.
Previously:
$ git push
fatal: The current branch tproxy has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin tproxy
But now:
$ git push
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Delta compression using up to 16 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 1.28 KiB | 1.28 MiB/s, done.
Total 4 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
remote:
remote: Create a pull request for 'tproxy' on GitHub by visiting:
remote: https://github.com/thushan/scoop-main/pull/new/tproxy
remote:
To github.com:thushan/scoop-main.git
* [new branch] tproxy -> tproxy
branch 'tproxy' set up to track 'origin/tproxy'.
To enable this behaviour, set a boolean configuration globally (or for the local repository) with:
git config --global --add --bool push.autoSetupRemote true
Latest Git for Debian Distros
To install the latest and greatest Git versions on your Debian flavoured installations, add the repo:
sudo add-apt-repository ppa:git-core/ppa
sudo apt update
sudo apt upgrade
Global Git Settings with .gitconfig
Global .gitignore
Sometimes you want to ignore files across all your git projects (eg. .DS_STORE
or thumbs.db
) and you can opt to use a global one stored in ~/.gitignore
and reference that in your ~/.gitconfig
. This cleans up your .gitignore
to focus on what’s most important for that repo.
Firstly setup your global git ignore in your home folder - note I’m appending just in-case you’ve already got something there!
echo '.DS_STORE' >> ~/.gitignore
Then we need to tell .gitconfig
to reference the file we just created.
git config --global core.excludesFile ~/.gitignore
git config --global core.excludesfile %USERPROFILE%\.gitignore
git config --global core.excludesfile "$Env:USERPROFILE\.gitignore"
Some useful things to add to the global .gitignore
can be things like:
.DS_Store
.vscode
.idea
node_modules
thumbs.db
The negative side to this is that some users of your repository may not also have these in their global and thus inadvertently add these in later.
Exporting your repository without git artefacts
Sometimes you just want to export your git repo without the git gunk. Here’s something akin to svn export
from the old days using the git archive
command.
You can simply zip up a cloned repository immediately with:
git archive --format zip --output /tmp/source-blah.zip
Or take it a little further, tar it up and BZIP it nicely:
git archive --format=tar --prefix=${PROJECT}-${VERSION}/ ${RELEASETAG} | bzip2 -9 > ${CURRENTDIR}/${PROJECT}-${RELEASE}.tar.bz2
git archive --format=tar --prefix=xbmc/ 3.2.1 | bzip2 -9 > xbmc.3.2.1.tar.bz2
But what if you have files that you want to exclude? Don’t worry, they’ve thought of that too with the .gitattributes
file that details what we should ignore in an export:
/target export-ignore
.gitattributes export-ignore
.gitignore export-ignore
.gitkeep export-ignore
Rebase commits since last push
With branches being so free in git, we make a lot of them, we also do lots of commits (at least I do). But before pushing them, I like to squash them where appropriate.
git rebase -i origin/feature-x feature-x
It’s only the local commits I squash rather than squashing the whole lot - which requires you to do a force push
(instead let your merge after a PR squash your commits).
Sign your git commits
See Signing Git Commits, became too much in one heading to have it here!
Sign previous commits
If you want to sign your previous commits you can exploit the use of the git rebase --exec
feature by signing all previous commits until a commit hash.
So let’s take this historical view of a repo:
$ git log --pretty=format:"%h - %an, %ar : %s"
b0f59fc - Thushan Fernando, 2 hours ago : Fixes issues with multiple tabs not containerising.
6abfdaf - Thushan Fernando, 2 months ago : fixes some formatting for figures.
7386c91 - Thushan Fernando, 2 months ago : Fix invalid dates on notes.
5fd5c8b - Thushan Fernando, 2 months ago : Hides last modified if it's the same as pubdate.
15482c5 - Thushan Fernando, 2 months ago : Adds last modified to posts.
f806691 - Thushan Fernando, 2 months ago : Slice of authors to flatten lists.
6e5283a - Thushan Fernando, 2 months ago : - Updates layout for home page view
5857b50 - Thushan Fernando, 4 months ago : Adds ATOM feed from kaushalmodi
594536d - Thushan Fernando, 4 months ago : Adds RSS+XML header.
fc25cf4 - Thushan Fernando, 8 months ago : TABS: radius on the border.
3453c6a - Thushan Fernando, 8 months ago : Selects first index in Tabs.
c771b2d - Thushan Fernando, 8 months ago : Align dots.
2885cd6 - Thushan Fernando, 8 months ago : Tab styling.
If you want to sign all commits until 594536d
we simply run:
git rebase --exec 'git commit --amend --no-edit -n -S' -i 594536d
Checkout new branch from a base branch
Sometimes you branch, find you want to something else but want to re-branch from the base branch (example: master
):
[working-branch] $ git checkout master
[master] $ git checkout -b new-branch
[new-branch] $ git ...
Short circuit having to revert to your base branch:
[working-branch] $ git checkout -b new-branch master
[new-branch] $ git ...
Prune local branches not in remote repository
Clean up any local branches tracking a remote branch that no longer exist with:
git remote prune origin
It’s advisable you give it a dry run first just to make sure:
git remote prune origin --dry-run
If you’ve got a lot of branches it’s pruned, you can also do a little house-keeping with:
git gc
Deleting a remote branch
If you want to clean-up remote branches, you can do that in two ways:
git push origin :[BRANCH]
Or in git v1.7.x+ something a little easier to read:
git push origin -d [BRANCH]
Search in git logs
You can search commit messages or the code itself in the log:
git log --grep="updated SSL certificate" # searches the commit messages
git log -S"[STRING]" --patch # searches the code change and shows a patch of change
Visualise Git History Since Start of branch
git log --graph --decorate --pretty=oneline --abbrev-commit
Gives us something akin to this:
More tips…
Check out the git tips collection on github, so many!