Git Cheatsheet

Some tips and tricks on how to use Git

Posted by Christian Jung on Sat, Aug 1, 2020
In Git
Tags devops, iac, gitops, gitlab, github

Getting started with git

This is just a list of useful commands and practices I learned over time while using git.

Basic git workflow

The following chapters are the simple commands to get you started.

Clone a repository

Create a local clone:

git clone URI

Git supports different protocols, typically you use one of the below:

# clone for GitLab, GitHub etc. via HTTPS
git clone https://github.com/ansible/ansible.git
# if you want to commit to a repo, it is often more efficient to use SSH
git clone git@github.com:ansible/ansible.git

Edit locally

When you work in your local repository:

# review current status
git status
# after editing a file, save and commit
git add path/to/file
git commit -m "useful commit message"
# you can combine the two previous commands
git commit -m "commit and add files" -a
# delete a file from the repository
git rm path/to/file
# and commit the change
git commit -m "delete path/to/file since it's obsolete"

This was only saving your change locally and did not (yet) push it to your remote! You can do many changes without pushing to your remote, depending on your work style and collaboration mode.

Pull updates and push changes

Until now, you only worked on your local repository - typically you want to interact with a remote server like GitLab, GitHub or others, for collaboration.

# only fetch latest changes, but do not merge them!
git fetch
# get all changes in all remote branches - particularly helpful if you want to see what others changed in their branches - but does not merge them!
git fetch --all
# get latest changes from remote and merge them locally
git pull
# push changes to remote
git push

NOTE: If the remote has a newer version of the branch than your local repository, a git push will give you an error message. In this case run git pull again to fetch and merge the latest changes from the remote repository.

Review changes

Git keeps all commits and you can review them with git log. You can also see more details:

# history of all changes
git log
# git more details about a specific commit
git show <commit>
# show differences
git diff <commit>
# roll back previous change
git checkout <commit>
# switch back to last commit
git checkout HEAD

Create your own repository

I recommend to always use git - even if you’re not sure yet you want to keep your work. Creating a git repository is just one simple command and therefore comes with very little cost:

# create a work directory
mkdir my_new_project && cd my_new_project
# initialize repository
git init

Now you can do local edits, revert changes, do diffs and when you’re done, add a remote repository later. If you realize it was all in vain, you can just delete the entire directory.

Remote Repositories

Since git is a decentralized software management tool yo can add and remove remote repositories at any point in time and you can use multiple remotes as well.

# add a new repository
git remote add <name> <URI>
# get a list of all remotes currently configured
git remote -v
# remove a remote repository
git remote remove <name>

All git commands like pull, push, diff etc. support different remotes, so you can easily compare their different states and decide where to pull or push changes to/from. I find it difficult at times to work with too many remotes, and seem to get lost in what’s where, so I would personally suggest not to stress this concept too much…

Cleaning your local directory

When working with Pull or Merge requests you often have local branches which have been deleted on the remote repository. You can clean them up easily:

# delete remote branches from local working directory
git remote prune <name>
# identify local branches which no longer exist on the remote
git branch -v
# delete local abandoned branches
git branch -d <branch name>
# if you have uncommitted changes
git branch -D <branch name>
# do everything in one command, but only for branches which have been merged
LANG=C git branch -d `git branch -vv | grep deleted | cut -f3 -d' '`

Working with branches

Git loves branches. It’s always a good idea to create a new branch before you implement a new feature (remember the old days when you created script-v1.sh, script-v2.sh, script-20200802.sh and lost track which script has which change?).

# create a new branch from the current one
git checkout -b <new branch>
# switch between branches
git checkout <old branch>

Stashing

Sometimes you have a local change which you want to keep but not yet commit. Or you accidentally started to work in the wrong branch. Instead of copying your local changes to /tmp or similar hacks, you can use git stash.

# stash local changes without committing them
git stash
# apply the stashed changes again
git stash apply

You can also work with different stashes by assigning names, check git stash -h for more details.

Diff branches

Sometimes there are many changes you need to identify them. I find it useful to do the following list of commands:

# differences between branches
git diff <branch>
# sometimes the reversed output is more useful
git diff -R >branch>
# just find hte list of modified files
git diff -R <branch> --name-only

Merging branches

After you finished your work in the new branch, you want to merge it back to master (or any other branch).

# switch to the target branch, e.g. master
git checkout master
# merge changes from the other branch
git merge <branch>
# sometimes you want to review changes and apply them individually, this will use the editor specified in the EDITOR environment variable if you want to edit the changes
git checkout -p <branch>
# merge a specific file from the other branch
git checkout <branch> -- path/to/file

Solving conflicts

When merging branches conflicts often occur. While git is quite clever in solving many of them automatically, you will still have some which will require manual fixes.

# merge with master or other branch
git merge <branch>
# assume a conflict happens, solve it with your favorite editor
vi file/with/conflict
# add the files to your next commit
git add files/with/conflict
git commit -m "solving conflict" # or other meaningful commit message

Delete and cleanup

After your work is complete and has been merged, you can delete the local branch.

git branch -d <branch>
# or, if there are uncommitted changes you don't want to keep
git branch -D <branch>

Use check the chapter Cleaning your local directory.

Pull or Merge Requests

Git makes it easy to work with branches to keep track of new features, bug fixes, releases etc. To simplify collaboration in projects Merge Requests (GitLab) and Pull Requests (GitHub) can be used. These are not features of git, but capabilities provided by the respective platform. Specially when you’re new to git it can be difficult to differentiate between pure git functionality and these additional features.

Typical workflow

Merge or Pull Requests are a good way to collaborate on new features or code changes. My typical workflow looks like this:

  • make sure your local repository is up to date by running git pull first

  • create a local branch to start development (git checkout -b <new branch>)

  • make your changes, commit them and continue the typical workflow as described in basic git workflow

  • push the local branch to the remote (git push, doing this the first time, you will probably see a message the remote branch does not yet exist and how you fix that, e.g. git push -u origin local-branch)

  • you will see a link which will create the Merge or Pull Request - you can also navigate to the Web UI and create it from there

  • fill out the details, mark it as a draft or WIP (Work in Progress) - this will make sure nobody “accidentally” merges the branch until it’s ready

  • continue working on your branch (you can still push new changes to the same PR/MR, no need to delete it and create a new one!)

  • when you feel it’s ready, remove the draft or WIP flag

  • collaborate and discuss the proposed changes with your peers, push additional changes when needed

  • merge the changes

  • delete the branch created for this MR/PR

Merge from master

When working with MR/PR your branch might fall behind and new changes from master need to be merged into your branch:

# make sure master is up to date and optionally review changes
git checkout master
git pull
# switch back to your branch
git checkout <branch>
# and merge all changes from master
git merge <master>
# or, review them while merging
git checkout -p master
# pull and merge in one command
git pull <remote> <branch>
# push your merged branch
git push

Clean up merged branches

If you create a lot of branches to work on changes, you probably want to clean them up, after they got merged.

# clean orphaned remote branches
git remote prune <remote>
# find local branches which no longer exist on the remote
git branch -v
# delete those local branches which no longer exist on the remote
git branch -d <branch>
# if the branch was not fully merged and you know what you're doing
git branch -D <branch>
# you can do this in one command
git branch -d `git branch -vv | grep gone | cut -f3 -d' '`

CI/CD Pipelines

A very powerful feature which builds on top of SCM are pipelines. In GitLab CI/CD has been integrated for a long time and GitHub recently introduced the concept of Actions. There are many other tools like Jenkins, Travis etc.

There are a few articles on CI/CD on this blog as well.