Git cheat sheet

Here is a collection of useful commands when working with Git. I have not included everything you can do with Git, but these are the ones I most often use in my day-to-day life. There is a lot more you can do though.

Creating and cloning

1
2
3
# The first time you use Git you should set up your user info:
$ git config --global user.name "<your-username>"
$ git config --global user.email "<your-email>"
1
2
# Setup a new git repo in the current directory
$ git init
1
2
3
4
5
6
# Clone a remote git repo to your local machine. If you don't specify <target-folder>
# it will default to making a new folder with the name of the repo.
$ git clone <repo-url> <target-folder>

# Example:
$ git clone https://github.com/jjv360/nim-classes.git

Push and pull changes

1
2
# Check if your code is up to date or if there are uncommitted changes, or to see what branch you're on
$ git status
1
2
# Pull down the latest changes from the server into your local branch
$ git pull
1
2
# Fetch all changes from the server but don't update the local branch
$ git fetch
1
2
# Delete all your local changes (even commits) and put the branch back to the server's version
$ git reset --hard
1
2
3
4
# Add all changes and commit, then push to the server
$ git add -A
$ git commit -m "My commit message"
$ git push

NOTE: Don’t ever do a “force push”, with the -f flag. The most common case of a push error is when someone else has made changes to that branch on the server and you didn’t have those changes yet when you did your commit. In that case, just do a git pull to fix your local branch and then git push again.

If you absolutely have to do a force push (really you shouldn’t though), make sure you tell everyone else who works on this code to reset their branch to the server’s version before making any changes themselves, or else they will just get corrupted as well:

1
2
3
4
# Reset branch to the server's version
$ git checkout <branch-name>
$ git fetch
$ git reset --hard origin/<branch-name>

Branches

1
2
# Create a new branch without switching to it
$ git branch <new-branch-name>
1
2
# Switch to a branch
$ git checkout <branch-name>
1
2
# Pull changes from another branch into your current branch
$ git merge <branch-name>
1
2
3
# Pull the latest code from the server's "dev" branch into your current branch
$ git fetch
$ git merge origin/dev
1
2
3
4
5
6
7
8
9
# Switch to an exact commit, and enter "detached HEAD" mode
$ git checkout <commit-hash>

# Turn that commit into it's own branch and exit "detached HEAD" mode
$ git branch <new-branch-name>
$ git checkout <new-branch-name>

# Or return to an existing branch and exit "detached HEAD" mode
$ git checkout <existing-branch-name>

Dealing with merge conflicts

The merge command will ensure your local changes to the branch, if any, are applied “on top” of the newly merged code. You will not lose your changes. This does mean that conflicts can occur, if the same piece of code was changed on your branch as well as the merging-in branch. When this happens, Git will enter a “conflict resolution” mode. The affected files will have sections that look like this:

1
2
3
4
5
<<<<<<< HEAD
let x = 2
=======
let x = 3
>>>>>>> other-branch

The structure of these conflict blocks looks like this:

  • First the <<< line marks the start of the conflict.
  • Next comes the code as it was on your branch.
  • Next there’s a separator =====.
  • Then comes the code that is coming in from the merging-in branch.
  • Finally the block is ended with >>> other-branch-name.

You now have to manually fix the code here. You can remove the entire block and keep the code you want. You can even change code in other places if you like, to ensure everything still works. Do this for all merge conflicts. If you’re using Visual Studio Code, you can easily see all merge conflicts in the Git tab on the left.

Once you’ve fixed all conflicts, you can “resume” the original merge by simply doing the commit:

1
2
3
# Resolve the conflict and exit conflict resolution mode
$ git add -A
$ git commit -m "Merged X and fixed conflicts"

If you don’t want to fix the conflicts and just want to cancel this merge instead:

1
2
# Cancel the conflicted merge and exit conflict resolution mode
$ git reset --hard

Dealing with Windows / Mac / Linux compatibility

Git has built-in support for automatically converting line endings and file permissions, so this may already be fine for you. Howver, I’ve always had trouble with this, most likely since I use Resilio Sync to sync my work folder between my PC and my MacBook. The first time I use Git on a new machine, I run these commands to ensure there are no issues:

1
2
3
# Automatically convert CRLF to LF when checking in to the server, and back to 
# CRLF when checking out on Windows.
$ git config --global core.autocrlf true
1
2
# Don't commit changes to file permissions.
$ git config --global core.filemode false

Merging PRs & releases

The usual process used when multiple people are working on a codebase, is to have a master branch which represents your “production” code, a dev branch which represents your latest “dev” build, and then individual branches for each PR or change. Usually, when a build is created, you would merge the latest PR branches into dev and update the version number.

I’ve found that doing this entire process locally works much better and prevents problems with any CI system you might have for auto-deploying builds. Doing it this way allows you to locally test the new version before pushing it up to the server, and you can always revert if a certain PR caused a problem, and do the build again without that PR.

GitHub even has good support for this, meaning that once you do finally push the dev branch up, it will automatically mark those PRs you merged as “merged”.

One thing to note about Git, is that when you do git fetch (or git pull) it downloads a local copy of all remote branches and keeps them up to date locally. These branches are all available with an origin/ prefix (assuming your remote is called origin). You can use this to pull in PR branches as well for your release, for example if a PR branch is called feature/save-backups you can now do git fetch and git merge origin/feature/save-backups to pull that PR into your local branch.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Do a release of a new version of your app! First make sure you're on your dev branch:
$ git checkout dev

# Make sure your dev branch is up to date with the server:
$ git pull

# Pull in all PRs you'd like to include in this release, remember the "origin/" prefix:
$ git merge origin/pr_branch_1
$ git merge origin/pr_branch_2

# Update your app version... Update the files with your version info (like package.json, etc) and then commit:
$ git add -A
$ git commit -m "Updated version to XXX"

# Now test your app locally. If all goes well, you can now push this build to the server:
$ git push

# If things did not go well, you can undo all of this locally:
$ git reset --hard origin/dev

If you’re using GitHub, it’s a good idea to create a Release tied to the dev branch after each new release. Besides being a good way of keeping a changelog, it also creates a git tag tied to that exact commit, so you can always go back to the code as it was at that moment in time. For example, if you wanted to do a hotfix on an old version of your code:

1
2
3
4
5
6
7
8
9
10
11
12
# Ensure tags are up to date
$ git fetch

# Go to the code as it was for a certain release. In this example, the tag was "v1.0.23"
$ git checkout tags/v1.0.23

# Push a hotfix for this version, and create a branch for it
... do code changes ...
$ git branch v1.0.23-hotfix
$ git checkout v1.0.23-hotfix
$ git add -A
$ git push

Forks and remotes

Sometimes you want to work on someone else’s repo, but you don’t have write access or you are just making modifications for your own use. If you’re using GitHub, when you create a “fork” it will copy the repo to your local account, but will keep a reference to the original repo. This is called the upstream repo.

1
2
# Check the URLs for your remotes
$ git remote -v
1
2
3
4
5
# Add the upstream repo URL if necessary
$ git remote add upstream <url>

# Example:
$ git remote add upstream https://github.com/jjv360/nim-classes.git

You will now have two remotes on your git repo:

  • origin : Your copy of the repo on the server. This is the default remote.
  • upstream : The original repo.

NOTE: With Git, every remote’s branches are available locally with the remotename/ prefix. A “fork” is simply a repo that has an upstream remote. At this point, there are three “groups” of branches: The branches on your local machine (no prefix), the branches on your server (origin/ prefix), and the branches on the upstream repo (upstream/ prefix).

Take for example the master branch. You have "master" which is your local machine’s copy, you have "origin/master" which is the branch as it exists on the server, and you have "upstream/master" which is the branch as it exists on the upstream repo. You can git checkout or git merge any of these at any time.

These commands can be used to pull in changes from upstream. This assumes you’re syncing the master branch.

1
2
3
4
5
6
7
8
9
# First ensure you're on the right branch and it's up to date
$ git checkout master
$ git pull

# Now make sure the local copy of upstream is up to date
$ git fetch upstream

# Now pull upstream's changes into your branch
$ git merge upstream/master
  • Copyrights © 2015-2021 jjv360

请我喝杯咖啡吧~

支付宝
微信