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:

Git history since start of branch / fork.
Figure 1. Git history since start of branch / fork.

More tips…

Check out the git tips collection on github, so many!

Related Articles

Post is 5014 days old, comments have been disabled.