This article assumes basic knowledge of Git. If you're new to Git checkout Intro to Git
GitHub
GitHub, GitLab and Bitbucket are also popular online repository managers. For this tutorial we will use GitHub but all of these online repository managers are very similar. I've worked with all 3 at various companies and they're all easy to use. GitHub is the most widely used and talked about since most of the popular open source libraries are hosted on GitHub. The information in this article also works for Bitbucket and GitLab.
Getting Started
Sign Up
If you already have a GitHub account you can of course skip this step.
Go to GitHub and create an account. Most GitHub features are free now unless you're running a company with a larger team. Even if your company needs paid services you won't have to pay more. Your company will add your to their team.
As with any service make sure to use a strong password. If you're storing projects that get pushed out to the web you don't want anyone to gain access and add malicious code. Select a free plan and verify your email.
Set up a GitHub repo
Once you complete the sign up set up your project as a new repository. I will also refer to your repository on GitHub as your "remote" repository.
You can name your repository anything you want. Usually the name of the project is most appropriate.
Generally its ok to leave it public as long as it doesn't contain any code that needs to stay private.
Frequently Used Commands
Clone
git clone <repository name>
If you want to download some code from GitHub you have several options. You can download a zipped folder containing all of the project files. Or you can "clone" the repository to your computer. A cloned repository retains a link to its remote on GitHub. Then you can sync project files on your computer with the files on GitHub.
Open your terminal and type git clone https://github.com/lodash/lodash.git
to clone the lodash library. This will also create a folder called lodash
for the project files.
Normally you will use git clone
when you want to contribute new code to a project. If a project is private you will need to have permission to clone it. You will need to provide your login credentials before GitHub will copy the files to your computer.
Checkout
When you clone a repository the default branch will be checked out. Usually this will be main, master, or develop. In this article I will just refer to this as the default branch.
Push
git push
Once you make changes to your cloned Git repository you will need to move or "push" them to GitHub. git push
will copy all local commits to your GitHub repository. Unless you specify otherwise your changes will be pushed to the currently checked out branch.
Depending on your team's preferred workflow you may want to push to a feature branch. Always double check which branch is checked out before you push to remote using git status
.
If you made a commit to the wrong default branch no need to panic.
Simply create a new branch
git branch <branch name>
Remove the commit from your default branch.
git reset HEAD~ --hard
Now checkout your new branch.
git checkout <branch name>
Now you can push your new feature branch to GitHub. Using git push -u origin <branch name>
Notice this command has a few additional flags. -u
is shorthand for --set-upstream
which lets GitHub know that it needs to track the changes in your new branch. origin
is a reference to your remote repository.
If you try to push a new branch to GitHub without these flags you'll get a friendly reminder from Git.
Fetch
git fetch
I usually run git fetch -p -t --all
See what commits were made to your remote branch. Adding the --all
flag will fetch changes from all of your branches. I usually add this flag so I don't forget to pull changes into other branches. Adding -p
will remove any references to branches that were deleted from your remote repository. Adding -t
will fetch any remote version tags that were created since your last fetch. (We won't discuss tags here. You may not need this flag if you're working on a personal project with no versioning)
Pull
git pull
Merge or "pull" new changes from your remote branch onto your computer. Git pull is shorthand for git fetch
and git merge FETCH_HEAD
. FETCH_HEAD is the remote branch of your currently checked out branch.
Resolving Conflicts
Sometimes changes from your remote branch conflict with local changes. If this happens you will need to resolve the conflicts before you can proceed. Usually this happens when you have another team member who is working in the same file or when you removed a lot of code in a previous commit.
Resolving merge conflicts can seem daunting at first but don't worry. You can't really mess anything up permanently.
If you're using VSCode you will get a nice interface to resolve conflicts. You will be able to choose between "current" and "incoming" changes. You'll see some ugly characters added to your files. HEAD (Current Change)
will be a change from your default branch. (Incoming Changes)
is a change in your current checked out branch. (Its a little counterintuitive)
<<<<<<< HEAD This is an edit on the default branch ======= This is an edit on the branch >>>>>>> current checked out branch
If there are a lot of conflicts it may take a little while to resolve all of them.
If you want to stop the merge run git merge --abort
to return to your original state. If you think you made a mistake while resolving a commit just run git reset --hard
and run git pull
again to start your merge again.
Rebase
git rebase <branch name>
Rebase is an alternative to merge and is sometimes considered to be a more advanced Git feature. It can be a little scary at first but I think its worth covering here because some teams do prefer it.
When a typical merge happens changes from 2 branches are combined. If your current branch contains all of the changes from your target branch merging is simple. Your current changes just get added on to your target branch. But if both branches have changes it gets a little more complicated. Git will have to make an additional commit to merge both all of the changes into a single branch. This additional commit doesn't change anything about the way your code works and some developers argue that it actually represents a more accurate project history. However some teams prefer a more linear history without merge commits.
This is where rebase comes in to play.
Rebase will temporarily remove commits from your current branch, add the commits from your target branch, then add your commits from your current branch.
I personally use both rebase and merge. I like to use rebase on my personal project but my work team prefers merge. Its really just a matter of preference.
Generally I find it best to rebase unpublished branches or branches where I am the only author. Rebasing changes your repository's history so if you have multiple people working on a branch and history changes it can cause issues for your coworkers if they pulled down commits that you just rewrote. I find it best to hold off publishing commits until you are ready to add your changes to the default branch.
Pull Request
If you are working with a team or contributing to an open source project you will usually need some else to review your code. So before you can integrate your changes into the default branch you will need to create a Pull Request or PR.
To do this in GitHub click on the "Pull Requests" tab and then click the "new pull request" button. Select the branch you want to merge. GitHub will compare your selected branch with the default branch and let you know if there are any conflicts. If there are conflicts you must resolve them before you can merge.
If GitHub says the branches are ready to merge click "create pull request". Here you will see a text field where you can add an explanation of the changes you want to add to the project. This is another time you will want to refer to your team's practices. My work team has a preformatted template for making pull requests.
If your team doesn't have a PR template just be sure to add a detailed explanation of your changes and the problem you are solving. If you have an issue or ticket number you may want to include it. You may also want to explain how you've tested your changes.
On many teams you will be required to get another team member or your team lead to review and approve your changes
For personal projects I still create PRs for myself. It just helps me keep track of changes and I like to review all of my changes before I add them to my default branch.
Squash
Squashing combines 2 or more commits into a single commit. So why would you do this? Well sometimes you want to reduce the number of small commits made to your main branch. Having a lot of small commits will add to your repository's history.
There is no git squash
command. Squashing is done using rebase.
I always like to squash all commits when I create a PR. This way I don't have a lot of small commits like created tests
or fixed styles
. Instead I add one large commit with a detailed commit message. GitHub provides this option when you merge a PR. I don't usually squash using the command line.
Squashing also rewrites history so follow your team's best practices and don't remove someone elses commits unless your team squashes commits when merging PRs.