Reset or sync local branch to a remote repository
Tags: opensource, git, syncing, beginners
Published: 2019-11-15 05:38:26

Header image: “Git Branches” by [Atlassian](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow) under [CC BY 2.5 Australia](https://creativecommons.org/licenses/by/2.5/au/)

You want to contribute to an opensource project, but you want to work from the latest copy of the software and the fork you have is out of date, how do you sync your local copy with the upstream project or your origin fork.

Lucky git can do all of that, so let me show you how.

##TLDR:
```bash
# Need to remember the command and have your upstream remote already?
git fetch upstream
git checkout master
git merge upstream/master
git push origin master

# If you are a madman or know that you local repo didn't change
git checkout master
git pull upstream master
git push origin master
```

#Using the Command Line to sync your fork to the original repo on Github

First, the easiest, cleanest, and easiest to understand is generating a clean fork.

##Cloning
```bash
git clone git@github.com:YOUR-USERNAME/YOUR-FORKED-REPO.git
```
If you already have a fork and you want to update it, the steps a slightly different.

##Adding Remote
```bash
# Check if you have a remote to the original repo. If not, it should return origin.
# Optionally add -v flag for more info
git remote
> origin
# If you don't have a remote to the original repo, add it with  
git remote add upstream git://github.com/ORIGINAL-REPO-USERNAME/REPO-YOU-FORKED-FROM.git
```

##Update from Original Repo
Now you have added a remote that points to the original repo, much like how you usually interact with the fork in your Github. Time to get the latest update. 

You have a many options here fetch/merge, fetch/rebase, fetch/reset --hard, or pull.
So let us go through and see their tradeoffs.

### For fetch/merge(The recommended method by Github)
```bash
# Fetches copy of repo from upstream and creates a new commit that is the merged
# result of combining commits from the upstream version and your local copy.
git fetch upstream
git checkout master
git merge upstream/master
```

### For fetch/rebase(Try to only use in private repos)
```bash
# Resets your local master branch to that of upstream and then rewrites 
# the changes over your local master branch.(Changes history of commits)
git fetch upstream
git checkout master
git rebase upstream/master
```

### For fetch/reset --hard 
```bash
# This command will destroy local changes to your current branch and your 
# local copy will reflect the original repo.(Removes local work)
git fetch upstream
git checkout master
git reset --hard upstream/master
git clean -f -d
```

### For pull
```bash
# A pull request performs a `git fetch` and then `git merge FETCH_HEAD`
# Good for writing to a clean branch or repo. (but can be conflict prone otherwise)
git checkout master
git pull upstream master
```

##Pushing to forked Repo
You may now push the local copy to your fork or simply begin working again.
```bash
# Push local changes to your origin fork
git push origin master
# or 
git push
# Sometimes rebasing will require you to force the changes when pushing to your fork. 
# In that case, you will need to force the push.
git push -f origin master 
```
##Extra Tips
**If you are using a method that discards your local changes, these two commands are helpful to store your changes for later:**
```bash
# To store your changes
git stash
# To get the changes back
git stash pop
```

**If you have just fetched and want to know the difference between what you fetched and your local copy before merging:**
```bash
# Returns any differences between two branches
git diff remotes/upstream/master master
```

**If you want to see where your copy of upstream master is stored:**
```bash
# Returns all branches, including remote tracking-branches
git branch -va
```
All done :)

#Resources
- http://ndpsoftware.com/git-cheatsheet.html#loc=workspace
- https://www.ocpsoft.org/tutorials/git/reset-and-sync-local-respository-with-remote-branch/
- https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/syncing-a-fork
- https://stackoverflow.com/questions/9646167/clean-up-a-fork-and-restart-it-from-the-upstream/9646323
- https://stackoverflow.com/questions/7244321/how-do-i-update-a-github-forked-repository
- https://longair.net/blog/2009/04/16/git-fetch-and-merge/
- https://git-scm.com/docs/git-pull
- https://stackoverflow.com/questions/292357/what-is-the-difference-between-git-pull-and-git-fetch