Git Commands I Keep Forgetting

May 15, 2019 · 690 words · 4 minute read

This is my Git cheat sheet. There are many like it, but this one is mine.

My cheat sheet is my best friend. It is my life. I must master it as I must manage my master.
The Repository Committer’s Creed

Git is perhaps the standard way of versioning code these days, but there are some details I can’t seem to remember, so I’ve noted them here. This isn’t a complete Git guide, there are enough of those.

While Git can be used with remote repositories, everything is local first.

Cloning

If you don’t specify a folder, git will clone the repo into a new directory with the repo’s name. I always expect the default to be into the current directory. Instead aim it somewhere, e.g.

git clone <my-repo.git> . # into the current directory
git clone <my-repo.git> <path>

Submodules

A submodule is code in a sub-folder of your repository, that is in itself managed as a git repository. This way you can import other libraries.

You can add a submodule with:

git submodule add <my-submodule-repo.git> <path>

Changes within the submodule are not tracked as part of the parent git repository. The main thing to remember is that if you clone a project that uses submodules you have to amend the clone command thus:

git clone --recurse-submodules <my-repo.git>

and this copies the content as well, otherwise you’re just left with the stub. If you forget that, then use:

git submodule update --init --recursive

git fetch and git merge work as usual within the submodule for keeping it up to date.

Basic Setting Up

git init  # within an existing directory, or
git init new-repo-name  # to create a new directory for the repo

This will add the hidden .git folder which manages all the git tracking. If you want to get rid of Git tracking, then delete this hidden folder.

Adding a remote

git remote add origin https://github.com/YOUR-USERNAME/YOUR-REPOSITORY.git
git push -u origin <branch>

The -u means --set-upstream and isn’t needed on subsequent calls to push unless you wish to change the target of push, e.g. when you’ve switched to a different branch.

Syncing with Remotes

Always do a

git fetch

before anything else, otherwise git status will not be up to date and give you misleading info if there’s been any change on the remote.

Committing without Commit Comment

Normally when you commit you need to add a message, which can be added inline with the -m flag. This is normally fine, but sometimes you don’t have a sensible commit message to add, e.g. when you’ve done nothing but corrected another rogue spelling mistake in the comment, it’s a pain. You can add a command alias with

git config --global alias.nccommit 'commit -a --allow-empty-message -m ""'

Stack Overflow

and then just do git nccommit instead.

Global gitignore

You can create a global gitignore file for yourself that works in all your projects. This is great if you want to avoid seeing various temporary files (e.g. Emacs auto-save or undo-tree) in all your repositories and want to avoid adding them to every project’s gitignore file. The documentation shows it being in a dot file in your home directory, but it can be anywhere. Syntax is the same as a normal gitignore file.

$ git config --global core.excludesfile ~/.mydotfiles/global_gitignore

Github with SSH

It’s normal to work with SSH and git, but it’s not so obvious on Github, where the general push is to use access tokens.

First create an SSH key in the usual way, using your Github email address. Github has certain minimums of the type you need to create.

$ ssh-keygen -t ed25519 -C "your_email@example.com" -f ~/.ssh/id_ed25519/github

Then login to Github and copy in the public key, choosing ‘authentication’ as the option (as opposed to using it to sign commits).

Then create an entry in your ~/.ssh/config file for Github, using the keyfile from above. Remember to specify the username as “git”, and not as you might expect, your Github username.

# Github
Host github github.com
	Hostname github.com
	User git
	IdentityFile "~/.ssh/id_ed25519/github"
	IdentitiesOnly yes

Then you can clone a repo with git clone ssh://git@github.com/<username>/<reponame>.git and work as usual.