I’ve used Git for many years but it can still trip me up. At times I’ve worked primarily in a GUI (like Sourcetree or Fork), and other times directly on the command line. I’ve worked on projects where I’ve been the sole developer and others where I’m part of a large team. Regardless of the tools or context, I’ve learned there are certain need-to-knows. Here’s a list of useful Git concepts and commands for my reference and yours.
Note: the following is not an exhaustive list but rather the thing I keep coming back to and/or regularly forget. For deeper explanations, see the list of resources at the foot of the article.
Table of contents
- Starting work
- Committing updates
- Save changes temporarily
- Staying current and compatible
- Reviewing your activity
- Fixing things
- Miscellaneous handy things
- Useful GitHub stuff
- Useful external resources
Create a remotely-hosted repo
Option 1: Create a new repo in your Github account
This generates a new, empty repo (optionally initialised with a README).
Do this when you will be working on a new, dedicated project rather than contributing changes to a pre-existing one.
Option 2: Create repo from a “template repository” (owned by you or someone else)
This generates a new repo with the same directory structure and files as the template. It’s a good option for starting your own new, potentially long-lived project from a solid starting point.
Unlike a fork it does not include the entire commit history of the parent repository. Instead it starts with a single commit.
Github Reference: Creating a repository from a template
Option 3: Fork an existing repo (usually owned by someone else)
This generates a new repo which is a copy of another repo, including its commit history. Your commits will update your copy rather than the original repo.
Do this by clicking the Fork button in the header of a repository.
This is good for (often short-lived) collaboration on an existing repo. You can contribute code to someone else’s project, via PRs.
Github Reference: Working with forks
Start locally by cloning
clone creates a local copy on your computer of a remote (Github-hosted) repo.
You might be cloning a repo you own, or one owned by someone else (to use its features in your project).
Your local copy will, by default, have its
origin remote set to the Github repo you cloned.
I cloned an empty new project
We’re in easy streets. The default remote is set exactly as you want it. Just write code,
push at your leisure, and
pull if/when you need to.
I cloned a pre-existing project (owned by me or someone else):
I plan to use it in my own, separate project
You might want to cut all ties and have a clean slate, git-wise.
Alternatively you might want to keep the original
remote available so you can pull in its future project updates, but reset the
origin remote to your new/target repo.
The source repo is my fork of a project to which I want to contribute
See Working with forks for how best to stay in sync and open PRs.
Duplicating (also knows as “duplicate without forking”)
This is a special type of clone. I know this is an option, but it‘s not one I’m familiar with or have had call to use. I can refer to Duplicating a repository if need be.
Start locally from a blank slate
Although cloning is the easiest way to get started locally, ocassionally I start by coding from scratch instead.
Remove a remote from your local settings:
Rename a remote:
Configure your favourite editor to be used for commit messages:
git st as a shortcut for
git status (to stop me mistyping as “statsu”):
Configure any setting:
Staging, unstaging and deleting files
reset (the opposite of
Delete a physical file and stage the deletion for the next commit:
Commit with a multi-line message:
Commit with short message:
Stage and commit all changes in a single command (note: doesn’t work with new, untracked files):
Show all local branches:
Show all local and remote branches:
Show branches you last worked on (most recently commited to):
Save current state to new branch but don’t yet switch to it (useful after committing to wrong branch):
Create and switch to new branch:
Switch to an existing branch:
Save typing by setting the upstream remote branch for your local branch:
Delete local branch:
Save changes temporarily
stash is like a clipboard for git.
Staying current and compatible
fetch remote branch and
Merge another branch (e.g. master) into current branch:
git rebase can be used as:
- an alternative to merge; and
- a means of tidying up our recent commits.
As an alternative to merge its main pro is that it leads to a more linear therefore easier-to-read history. Note however that it is potentially more disruptive therefore not right for every situation.
Say I’ve been working on a feature branch and I think it’s ready.
I might want to just tidy up my feature branch’s commits and can do this with an “interactive rebase”. This technique allows me to tidy my feature branch work to remove trivial, exploratory and generally less relevant commits so as to keep the commit history clean.
I might also want to bring in
master to ensure synchronicity and compatibility.
rebase sets the head of my feature branch to the head of
master then adds my feature branch’s commits on top.
While it’s a good idea to
rebase before making a PR, don’t use it after making a PR because from that point on the branch is public and rebasing a public branch can cause problems for collaborators on the branch. (The only exception to the previous rule is if you’re likely to be the only person working on the PR branch)
Rebuild your feature branch’s changes on top of master:
Force push your rebased branch (again, only when you’re unlikely to have/require collaborators on the PR):
Tidy a feature branch before making a PR:
Undo a rebase:
For more detail, read Atlassian’s guide to rebasing.
Reviewing your activity
Show commit history (most recent first;
q to quit):
Check if your feature branch is trailing behind:
Show changes that occurred in the most recent commit or a given commit.
Review differences between staged changes and last commit:
Review changes between a given version/commit and the latest:
Discard all your as-yet uncommitted changes:
Get your local feature branch out of a problem state by resetting to the state it is on the remote (e.g. at last
Undo all the changes in a given commit:
Alter the previous commit (change the message and/or include further updates):
Move current branch tip backward to a given commit, reset the staging area to match, but leave the working directory alone:
See what the app/site was like (e.g. whether things worked or were broken) at a given previous commit, noting the following:
- You’re now “detatched”, in that your computer’s HEAD is pointing at a commit rather than a branch.
- You’re expected to merely review, not to make commits. Any commits you make would be “homeless”, since commits are supposed to go in branches. (However you could then branch off.)
Return one or more files to the state they were in at a previous commit, without reverting everything else.
git st reveals a list of staged files including lots of strange files you don’t want there mixed with others you do…
Grab one or more commits from elsewhere and drop into your current branch:
Fix a pull that went wrong / shouldn’t have been done:
Miscellaneous handy things
Revert to the previous branch you were on
Useful GitHub stuff
- Review your branches on a repo
- Review PRs and issues you’re subscribed to, i.e. ones on which you were active or mentioned
- Review your or another user’s PRs
- If you are fixing something that was raised in a GitHub issue, link that issue in your fix PR’s sidebar under Linked Issues (rather than just mentioning it in the PR) and it will automatically close the issue when you merge.
Useful external resources
- Tips, tutorials and Cheat Sheets from Atlassian
- Need to undo an old commit? Committed to master by mistake? Get out of trouble with Oh Shit, Git!
- More getting out of trouble: Git Flight Rules
- Oh-my-zsh Git aliases and how to add your own
- The original Pro Git reference
- Git for Humans by David Demaree from A List Apart is a great intro to the concepts and basic commands.