Git is probably the most used developer tool (aside from operating systems, shells and browsers/editors) out there. It can be a lifesaver but if used wrong cause terrible headache. Here are some commands and snippets I’ve encountered and found useful.
I’m assuming that the default remote in these examples is
origin and a foreign remote is called
As example remote URL I will either use pseudo local paths, random urls or linux because it has infinite collaborators.
The default branch is
master and any other branch is mostly called
The example tag in these examples is in most cases
Git-LFS (Large File Storage) is a git plugin/subcommand that lets you save binary files outside of the git object storage. This saves some space when cloning and works faster. To install it, follow the instructions on the website.
Assuming you want to track
.bin files with Git-LFS:
- Change into project directory
- Initialize Git-LFS:
git lfs install
- Tell Git-LFS which files to track:
git lfs track "*.bin"
- Add the
.gitattributesfile and commit:
git add .gitattributes && git commit
Alternatively, you can skip/speed up step three by putting the following in the
.gitattributes file (create it if it’s not there):
*.bin filter=lfs diff=lfs merge=lfs -text
When run with no arguments,
git log shows a vi/less style commit history output.
But it can also be used for more specific stuff.
Show log for specific remote/branch/tag
The following command can be used to show the history of a specific tag or remote and/or branch:
git log remote/master
Show log for specific subdirectories
You can use the following command if you’re in a subdirectory of a repository and only want to see the local history:
git log -- ./
-- delimiter is used to make a clear separation between refs and paths.
This can also be seen in some git error messages.
A tag is like a bookmark on a specific commit. Mostly it’s a good practice to tag the version bump commits (if those are made).
While git tags can be seen as an appendage next to the commit id in
git log, it’s also possible to show all available tags.
I think the command below is self-explanatory:
git tag -l
Listing remote tags can either be done for the default remote:
git ls-remote --tags
Or a specific remote:
git ls-remote --tags remote
A tag can be created like this:
git tag v1.0.0
The tag will now show up in the git history as
v1.0.0 which is an often used scheme.
Btw have you heard of semver?
git push doesn’t submit patches by default, a flag is needed:
git push --tags
Deleting tags can be necessary when doing debug stuff (like CI that should build on every tag but there’s a bug in a script of a dependency that only runs on CI so you end up with something like
Local tags can be deleted quite easily:
git tag -d v1.0.0
When removing remote tags, it’s required to to a push:
git push remote :v1.0.0
You can see more info on this syntax in the section about
git push below.
Update: Since git 1.8.0, you can also use the following which is a bit more readable:
git push --delete remote v1.0.0
push command allows to submit changes to a remote.
When used without arguments in a properly set up repository, it will push all new (for the remote) commits on the current branch (or it’s remote counterpart) to the default remote.
Showing available remotes
All available remotes can be printed out by running:
git remote -v
Setting a default remote
A default (upstream) remote can be set by running the following:
git push -u remote branch
This sets the foreign remote called
remote as upstream that will be used by default when running
-u flag can be extended to
Adding a remote
Adding a remote can be done by running the following:
git remote add remote /path/to/repo/.git
When adding a remote remote (haha), a protocol and/or authentication might be required:
git remote add remote ssh://firstname.lastname@example.org:foo/bar.git
Deleting a remote
Deleting a remote can be done like this:
git remote remove remote
Changing a remote’s URL
When a repository was moved or there is some other stuff going on, a remote url can be changed by running the following:
git remote set-url remote /path/to/new/repo/.git
Note that by default, only the fetch url is updated by this command.
It’s also default for git to use only the fetch url when a push url is not explicitly set.
In case of local mirrors (see section about
git clone below) it might be required to set the push url to the original remote.
This can be done by appending the
--push flag after
set-url (and before the url).
Cloning means downloading/synchronizing a remote repository to/with your machine.
It’s used to get an initial copy of the repository (updating is done with
git pull instead).
Cloning in general
Most Git platforms mentioned above support cloning by passing the URL of the repository’s web frontend like the following:
git clone https://github.com/torvalds/linux
This will result in the repository being cloned into the current folder as
On some platforms, the URL might look more like
In this case, git will omit the
.git extension for the local folder.
Changing the output directory
To clone a remote repository into a folder other than the repository name, you can simply append it. If it does not exist, git will create it automatically. Example:
git clone /path/to/repo/.git ../otherName
The command above will result in the repository being cloned into the parent of the current folder as
You can also specify an absolute path.
Cloning as mirror
In some cases it might be wise to store an exact copy of a remote repository on another place. For instance when the connection to a remote repository is pretty slow or the network has a limited transmission rate.
It can be a good idea to clone a very remote repository onto a more local server and let local clients pull from there.
The remote repository can be cloned as mirror by appending the
git clone --mirror ssh://user@host:repo.git
The mirror can be kept up to date by running
git remote update.
This can be intervalled by using something like the following crontab which will update the mirror every fifteen minutes:
*/15 * * * * cd /path/to/mirror && git remote update >/dev/null 2>&1