Everything You Need To Know About Git
This is a cheatsheet of all the git commands that I’ve ever used in my career as a programmer and contributor of open source projects. I’m not a git power user (I use about three commands on a daily basis). From time to time, I still use this cheatsheet to for a quick lookup of a special command.
This is a Live Document. I won’t be updating it that often.
This is a tutorial for Unix and Git newbies.
Setting it all up from scratch
This provides a good tutorial for how to create a repo on github, use ssh-keygen to generate a SSH private/public key pair.
Basics
Forking
Forking is used when you contribute to a open source repository.
Assume:
- userA, userB, and userC all setup their computers with a Github account.
Suppose:
- userA wants to create an original repo called
ProjectName. - userB wants to fork the
ProjectNamerepo from usernameB. - userC wants to fork the
ProjectNamerepo from userB.
Git Tutorial For userA
Go to https://github.com/userA/ and click the “New” button. Name the new repo project-name.
-
On your computer, go to terminal and
cdinto the directory you want to host the local repo, then do:$ git clone https://github.com/userA/project-name.git``
-
Check that you have remote:
$ git remote origin``
-
Open the project in finder and in atom to edit the content of the folder.
$ open . $ atom .``
Alternatively…
On your computer, in Finder, make a new folder called project-name. Copy all the files you want to the ProjectName folder.
In the Terminal, do the following:
-
Type
cdinto the terminal then drag theproject-namefolder into the terminal. You’ll seedirectoryPathbeing auto-completed in Terminal.$ cd directoryPath -
Initialize the
project-namefolder as a git repo. This essentially makes this folder a “local git repo”.$ git init -
Link your “local git repo” to a “remote git repo” that you own. Call this remote git repo
origin.$ git remote add origin ssh://git@github.com/userA/project-name.git``
-
Make sure
originis an available remote and check the path.$ git remote # git remote -v``
-
Sync your local repo to your remote repo.
$ git fetch origin $ git add --all $ git commit -m 'Initial Commit!' $ git push origin master``
Note, if you added a LICENSE file or a README file from Github, make sure to do a
git pull origin masterbefore you do agit add --all. -
Now open a file within
ProjectNamein Atom or another text editor. Make some changes to the code. To sync your local repo with your remote repo, do this:$ git fetch origin $ git add --all $ git commit -m 'I made some changes!' $ git push origin master``
-
After you accept a pull request from userB, your remote repo is updated. Now you want to sync your local repo with your remote repo:
$
git pull origin master
Git Tutorial For userC
Go to https://github.com/userB/project-name and click the “Fork” button.
In the Terminal, do the following:
-
Type
cdinto the terminal and drag and drop the folder where you want to create the project folder from Finder into Terminal. You’ll see directoryPath being auto-completed in Terminal.$ cd directoryPath -
Make a new folder called
project-name.$ mkdir project-name -
Go into the
project-namefolder$ cd project-name -
Initialize the
project-namefolder as a git repo. This essentially makes this folder a “local git repo”.$ git init -
Link your “local git repo” to a “remote git repo” that you own. Call this remote git repo
origin.$ git remote add origin ssh://git@github.com/userC/project-name.git -
Populate the
project-namefolder on your computer (i.e., local repo) with the files from the remote repo’s master branch.$ git pull origin master -
List the files in your
project-namefolder to make sure the pull was successful. You should see this folder populated with files downloaded from the remote repo$ ls -
Link your “local git repo” to another remote git repo that userB owns. Recall you forked the
project-namerepo from userB. The upstream user’s (i.e., userB) repo. Call thisupstream.$ git remote add upstream https://github.com/userB/project-name -
Make sure
originandupstreamare both available remote.$ git remote -
Now open a file within
project-namein Atom or another text editor. Make some changes to the code. To sync your local repo with your remote repo, do this:$ git fetch origin $ git add --all $ git commit -m ‘I made some changes!' $ git push origin master -
To sync your local repo with userB’s repo, do the following:
$ git pull upstream master
Branching
When we develop software on a team of developers, everyone would work to commit changes to a development branch. Every new feature added would correspond to a ticket in Jira’s backlog. When you work on each ticket, you create a feature branch from the development branch and then you would submit a pull request to the development branch with the Jira ticket number in the commit message.
To illustrate how branching works, check out this toy repo
Other Useful Commands
Some useful things you can do when things go haywire or just to get the most usefulness out of git:
Revert to previous version of code
Revert your local repo to the previously committed version when everything still worked:
$ git log
# git will display the following:
# commit: <commitID>
# ...
# type q to exit the log
:
# force your local to the commitID
$ git reset --hard <commitID>
# force your remote to the commitID
$ git push --force origin master
Switching between branches
# checkout the alias of the remote e.g., origin
$ git remote -v
# switch to a new branch called boilerplate
$ git checkout -b boilerplate
# look at all your branches
$ git branch
# you should see git display the following branches for origin:
# b1 = master and b2 = boilerplate
# push local repo to boilerplate branch
$ git push origin boilerplate
Git won’t let me commit
Your local repo should never go out of sync with your remote repo. Git prevents you from pushing changes from your local repo to your remote repo if there are changes in your remote repo that you don’t have locally. If you don’t want to sync with your local repo with the remote and you just want to overwrite the remote repo with whatever you have locally, this is a useful command:
$ git push origin master --force
-
If you accidentally initiated a directory as a git repo, this undos the
git init:$ rm -rf .git``
-
If you don’t want to have to enter your password everytime when you push to a remote, then in the project local repo, do the following:
- Per the official guide from Github, you want to switch your remote URLs from SSH to HTTPS:
$ git remote set-url origin https://github.com/USERNAME/REPOSITORY.git
gitignore
The .gitignore file should be included in your local repo folder, which tells git to not add files and folders that you don’t want to share publically on Github to your remote repo. What kind of files are these?
DS_Storeand other metadata files that macOS create.envfiles which includes configuration for your application that may include secret keys that you don’t want people to know about.- Transient files from your working directory that aren’t useful to other collaborators, such as compilation products, temporary files IDEs create, etc. Prime example is the
node_moduleswhich tend to be large and people downloading your project can get from runningnpm installif they have the right dependencies listed inpackage.json.
In general, you should include the following in your .gitignore
lib-cov
*.seed
*.log
*.csv
*.dat
*.out
*.pid
*.gz
*.swp
pids
logs
results
tmp
coverage
# API keys
.env
auth.js
# Dependency directory
node_modules
bower_components
build
# Editors
.idea
*.iml
# OS metadata
.DS_Store
Thumbs.db
Advanced Topics
Submodules
Submodules is like a repo inside of a repo. See GitHub Blog for a brief tutorial.
Pro-tip: Use GitKraken to simplify the process of working with submodules. See Tutorial
Adding a submodule:
$ git submodule add https://github.com/kakawait/hugo-tranquilpeak-theme.git themes/tranquilpeak
$ git submodule update
$ git submodule init
$ git submodule add -b master git@github.com:xiaoyunyang/xiaoyunyang.github.io.git public
Removing a submodule
It’s painful with the command line. I was in a git hell for a long time and couldn’t get it working. I ended up using Gitkraken to remove my submodules and it worked like a charm.