Git Tutorial and Cheat Sheet
Learn and Use Git Fast: Git for Busy People This tutorial skips over some details as it is intended to accompany classroom discussion. However, it…
This tutorial skips over some details as it is intended to accompany classroom discussion. However, it does provide more hand-holding than a cheat sheet. This tutorial is a simplified and updated version of Andrew Burgess’ 2009 Tutorial on TutsPlus.
A Note on Syntax: Be sure to exclude the brackets [] in the examples below. Use your custom values instead.
The install section of the Git book provides details for Mac, Windows, and Linux environments.
$ git config --global user.name "Your Name" $ git config --global user.email "your@email.com"
Add text coloring to the bash terminal:
$ git config --global color.ui auto
$ git config --list
C:\users\%UserProfile%\Lists of Windows environment path variable shortcuts
Only done and needed for a new project (top-level folder). Leave out the repository (repo) name so it will default to “master.”
1. Navigate to your new project’s folder:$ cd C:\wamp\www\python\extreme-moves-app2. Now create a new git repo for the project:
$ git init
This creates (initializes) a Git repository in your project folder. The .git
folder that’s created and initialized tracks changes to your code and denotes it with a secure hash on each commit.
We always create a new branch (1) before and (2) when we intend to make drastic changes to the branch we are located in!
But, before we tell you how to create branches, this is how you view a project’s branches:
:$ git branch
First, checkout the branch you want to fork from. We call this the “parent” branch! Second, create a branch of that “parent”. Here are the steps:
1. Work on (i.e., checkout) the branch you want to fork:
$ git checkout [branch-name]
2. Create a new branch:
$ git branch [branch-name]
You either need to (1) be in the parent branch that you want to fork from or (2) state the parent branch explicitly. If you don’t explicitly state the parent branch, Git will assume the parent is the branch you’re currently in!
Create a new branch and switch to it simultaneously:
$ git checkout -b [branch-name] ([parent-branch-name])
-b
tells git to switch to [branch-name] once created
parent-branch-name
is optional, hence the parentheses. If excluded, Git defaults it to the branch you’re working in!
It’s best practice to always checkout a new branch before making major changes! But what if you’ve been coding for hours, saved your changes… and forgot to checkout and work from a new branch? Or even forgot to fire up Git? All is not lost. Just do this:
$ git checkout -b [new-branch-name] $ git add . $ git commit -m "rewrote core code. deleted old test files. reorganized folders"
Upshot: As long as you have not committed any files you are free to have the changes stored in any branch without affected your master/parent branches!
The staging area “holds” files and their changes for your next commit:
Per GitHUb, a commit is a permanent snapshot of all the files in your project at a particular point in time.$ git add .
The .
will stage all changed and untracked files. You may also use wild cards and specific file
names to stage certain files and types:
$ git add *.css $ git add hello.py
Staged and Unstaged files that have never been committed are accessible (read, write, delete) amongst all branches (yes even those you are not working in). However, if you edit and save the file after it’s been committed the first time, Git will not let you switch branches unless the file has been re-committed!
$ git commit -m "descriptive msg as to why code was committed"
The following will simultaneously stage and commit previously added (i.e., staged) files that have been modified.
$ git commit -am "message, so you know why that code was committed"
Note: This will not auto-stage newly added files. They will not be added and will remain untracked. So, you must manually add new files via $ git add .
To edit the commit message just type:
git commit --amend
Show default editor:
$ git config --global --get core.editor
Windows users may use Visual Studio Code, like so:
$ git config --global core.editor "code --wait" $ git config --global format.commitMessageColumns 72
Mac users can use nano:
$ git config --global core.editor "nano"
$ git commit -av
The git status command shows you which files were changed (modified) and new (untracked) since your last commit.
$ git status
This is done after we finish creating and testing a new feature. We merge the child branch into it’s parent branch. Upon a merge, the changes in the child will overwrite the existing files of the parent.
Merge a branch (child) into the branch you’re currently working on (parent) like so (make sure you’re in the branch you want the child branch to be merged into):
$ git merge [branch-name-I-want-to-merge]
Delete branch (child) after merging (into parent):
$ git branch -d [branch-name]
Delete branch that you never merged:
$ git branch -D [branch-name]
Experiment with the below and learn what they do!
$ git log $ git log --graph $ gitk --all #color gui
To view the history of a particular file:
$ gitk path/to/file
OR
$ git log -p -- path/to/file
OR show full history and diffs along with diffs with associated with file’s prior names:
$ git log --follow -p -- file
--
option tells Git that it has reached the end of the options and that anything that follows --
should be treated as an argument. For git log this only makes any difference if you have a path name that begins with a dash. –Dan Moulding
Stashing is a power user feature. Here are two use-cases of why and when to use git stash
$ git stashb. Create a new branch from the stash:
$ git stash branch upgrades/mega-filter
$ git add .b. Stash changes:
$ git stash
Always stage your changes before you stash! If you do not (1) stage your changes before stashing and (2) then switch to another branch, you will (3) receive a merge conflict error CONFLICT (content): Merge conflict in XYZ
when you attempt to recover your stashed files! You do not want this to happen! Always stage before stashing!
Now, you’re free to checkout any branch you want to work on! And, when you’re ready return to your stash, just do:
$ git checkout [branch-that-you-stashed]
$ git stash apply
Generate a new SSH key for GitHub:
NB: RSA signatures are no longer recommended for modern computers.
$ ssh-keygen -t rsa -b 4096 -C "your_email@example.com"$ ssh-keygen -t ed25519 -C "your_email@example.com" -f custom_name_to_save_as
Where:
-t
= Specify the digital signature algo to use
-C
= comment stored in the public key file. It serves the ssh key identifier
-f
= optional parameter used to save key file with a custom name. Default file name is the digital signature algo used (e.g., rsa.pub or ed25519.pub)
If you plan to connect your local Git environment with GitHub, the email address you use during set-up needs to match that of your GitHub account. By default your commits will contain your name and email address.
GitHub has an article on how to keep your email address private on their site. They mention that you’ll also need to change the email you use in your local Git to their private email alias. Feel free to experiment.
GitHub periodically deletes saved public keys if you have not used or verified them over a specified time. This will result in a Permission denied (publickey) error when connecting to GitHub through git bash over SSH.
The solutions are to either (1) generate a new public-private key-pair or (2) simply re-paste your pre-existing public back into GitHub. Let’s go with solution 2:
1. Turn on the ssh-agent:$ ssh-agent -s # If using MINGW64 (i.e., Windows users) type this instead: $ eval $(ssh-agent -s)2. Verify that your private key is loaded into SSH:
$ ssh-add -l3. If your key hash appears proceed to step 4. However,
$ ssh-add ~/.ssh/id_rsa
v
is the verbose
ouput indicator)
$ ssh -vT git@github.com
GitHub’s SSH documentation is better than Bitbucket’s. So once you’re set up on GitHub, log into your Bitbucket account, and do the following to connect it to:
$ clip < ~/.ssh/id_rsa.pub
$ ssh -T git@bitbucket.org
Cloning is primarily used to quickly get a local copy of a repository from the source code's owner. Cloning without forking is done when we do not intend to contribute to the original project. Unlike a fork, a clone does not maintain a connection with the original owner's source (i.e., upstream) repository.
When we clone a repo, we save it to our local drive. The process is as follows:
#Using https: $ git clone https://github.com/your-user-name/project-name [name-of-folder-to-clone-to] #Using ssh (note the repo name must end in .git): $ git clone git@github.com:your-user-name/project-name.git [name-of-folder-to-clone-to]NB: Cloning auto-creates an external pointer to the source repo called "origin" on your local drive
Although, forking is not permitted on private repos, you may clone and then submit pull requests for merges. If you use GitHub from the command line here is how you clone a private repo:
git clone https://Your_GitHub_Username:$your_GitHub_token@github.com/CodeSportLabs/programmable-nfts.gitUsing ssh:
git clone git@github.com:CodeSportLabs/programmable-nfts.git
NB:The repo is automatically tagged as origin when you clone it
git clone -b my-branch https://Your_GitHub_Username:$your_GitHub_token@github.com/CodeSportLabs/programmable-nfts.git
Cloning is also used as an intermediary step to transfer (or duplicate) a repo onto another git provider. If you need to transfer the repo to another provider (e.g., transfer from Github to Bitbucket), first initiate a clone as above, then proceed as follows:
# Step 1: Go to Bitbucket and manually create a new and empty repo with the name of the project you want to clone
# Step 2: On your local drive 'cd' into the project you just cloned in the prior steps
$ cd project-name
# Step 3: change the Github remote from 'origin' to 'upstream'*
$ git remote rename origin upstream
# Step 4: Finally, add the new Bitbucket repo as the 'origin'
$ git remote add origin git@bitbucket.org:your-user-name/project-name.git
# Step 5: Push all branches to Bitbucket once**:
$ git push -u --all origin
*NB: See What is the difference between origin and upstream on GitHub?
for a definition of these terms.The forking process is defined by manually creating a duplicate of a repo on your git provider’s website. Here is a nuance between forking and cloning:
A forked repository differs from a clone in that a connection exists between your fork and the original repository itself. In this way, your fork acts as a bridge between the original repository and your personal copy where you can contribute back to the original project using Pull Requests.
–Forking vs Cloning via Github
GitHub has solid documentation on forking, so we’ll punt in this section and refer you to their help doc called Forking a Repo. Here’s summary of the the workflow taken from the above link:
Forks are the first step in either proposing changes to someone else’s project or to use someone else’s project as a starting point for your own idea.
Forks are often used to propose changes for bug fixes. For example, instead of logging an issue for a bug you’ve found, you can:
- Fork the repository [make a remote repo] and then clone it to your local machine [make a local repo]
- Create a new branch were you plan to make your fixes
- Make your fixes (and test them)
- Push your fix from your local repo to your remote repo
- Submit a pull request to the project owner (Note: Pull requests are done on the Github/Bitbucket websites, not the command line)
–Forking a Repo via Github
Once you fork, you’ll also want to:
$ cd [project home directory] $ git remote add upstream git@github.com:ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git $ git fetch upstream $ git checkout master $ git merge upstream/master
$ git push origin master
First, refer to GitHub’s tutorial on creating a personal access token for the command line. Items in red should be customized to your use case:
curl -H "Authorization: token PLACE_GITHUB_TOKEN_HERE" https://api.github.com/user/repos -d '{"name":"PROJECT_NAME", "private":"true", "description":"DESCRIPTION GOES HERE", "homepage":"https://codesport.io"}'
NB: If you’re creating a repo for an organization, change:
https://api.github.com/user/reposto
https://api.github.com/orgs/COMPANY_NAME/repos
We are calling our remote, replica repo upstream
. “Upstream” is the naming convention when the local repo is the primary and source repo. Alternatively, we would name the remote repo origin
when the remote is the “primary and source repo”. For example, when we fork someone else’s project with the intent of doing a pull request, the remote repo would be the origin (i.e., the “primary and source repo”).
git remote add upstream git@github.com:GITHUB_USER_NAME/PROJECT_NAME.git
git push -u upstream master #NB: for first commit -u is shorthand for '--set-upstream' and activates branch tracking
If you have a brand new local project that you’d like to push out to GitHub, please be sure you’ve created an empty repo on GitHub first. This may be done via the command line. Or manually pressing a button on GitHub.
Below is the full workflow:
$ git remote add [name][url]
In the example below, the name of push destination [name]
is upstream and [url]
is git@github.com:codesport/repo-name.git:
$ git remote add upstream git@github.com:codesport/repo-name.git
Continuing with the example above, to push the current branch and set the remote as upstream do
$ git push --set-upstream upstream master
$ git push upstream master
For pre-existing repos that you have forked and are modding, use the below workflow:
Use git push
to send commits made on your local branch to a remote repository.
$ git push origin [your_local_branch_name]
Alternatively, you may use git push -u origin [your_local_branch_name]
the first time you push out an update.
Where: -u
is shorthand for --set-upstream
. This activates branch tracking. And, with tracking on, for subsequent pushes you just type git push
.
See these Stack-overflow Q&As for further context
View remotes associated with a given repo:
$ git remote
Push updates from your local machine to your remote repo (e.g., GitHub or Bitbucket)
$ git push remote_name branch_name
Use-case: renaming a local branch where you’ve done substantial editing and commits
Rename the local branch to the new name
git branch -m [old_name] [new_name]
Delete the old branch on remote – where [remote] is, for example, origin or upstream
git push [remote] --delete [old_name]
Or shorter way to delete remote branch [:]
git push [remote] :[old_name]
Push the new branch to remote
git push [remote] [new_name]
Reset the upstream branch for the [new_name]
local branch
git push [remote] -u [new_name]
If you misnamed a new local branch and haven’t done any editing or commits, you can delete it via:
git branch -d [bad_branch_name]
These tips were found on StackOverflow
Use Case: You have a personal GitHub account. Its SSH keys and token are already “installed” on your laptop. However, you started a new job and have a new GitHub account strictly for work
.Host github-personal-accnt-username HostName github.com User git IdentityFile ~/.ssh/id_rsa Host github-work-accnt-username HostName github.com User git IdentityFile ~/.ssh/id_ed25519
git init git config user.name work-accnt-username git config user.email work-accnt-email
github-work-accnt-username
account:
git remote add [origin|upstream] git@github-work-accnt-username:repo-owner-username/repo-name.git
git push -u [origin|upstream] [your_local_branch_name]
Where: -u
is shorthand for --set-upstream
. This activates branch tracking. And, with tracking on, for subsequent pushes you just type git push
NB: To further automate the process you can to auto-select which GitHub account to use based on your working directory.
git pull
A Pull Request happens when you (1) make changes to a branch (or a fork) and (2) request that the original owner(s) pull your changes into their repository. Hence, the term “pull request”.
Pull requests lie in the domain of social coding platforms such as GitHub and Bitbucket. While git pull
is a git command. Yangsu has a good tutorial where you may learn both by doing a simple example! Here are some quotes that sum things up:
Pull requests let you tell others about changes you’ve pushed to a GitHub repository. Once a pull request is sent, interested parties can review the set of changes, discuss potential modifications, and even push follow-up commits if necessary. — GitHub Help: Using Pull Request
…git pull
does agit fetch
followed by agit merge
. Agit pull
is what you would do to bring a local branch up-to-date with its remote version, while also updating your other remote-tracking branches. — Greg Hewgill