Confusing Terms in the Git Terminology
Tags: opensource, github, codenewbie, computerscience
Published: 2021-05-30 10:43:56

[**Git**](https://git-scm.com/) and [**GitHub**](https://github.com/) are at the core of open source in today’s programming world. However, there are a lot of confusing terms that often seem similar yet can have conflicting meanings and uses. Let’s demystify these confusing terms by decoding their underlying meanings.

**NOTE:** _This article expects some knowledge of Git and GitHub._

![Octacat gif](https://miro.medium.com/max/1600/1*ZIrFsOM49UJ7dlmATwkzIg.gif)

### Origin and Upstream

**From [Git Documentation](https://git-scm.com/doc):**

> When you fork a repo and clone it locally, then there is a default remote called **origin** that points to your fork on GitHub, not the original repo it was forked from.
To keep track of the original repo, you need to add another remote named **upstream**.

This confusion arises when you are working on the clone of a forked repo. **Upstream** is what you would use to fetch from the original repo to keep your local copy in sync with the project you wanted to contribute to. Meanwhile, **origin** is what you would use to pull and push code to your fork, and thereafter you can contribute back to the upstream repo by making a pull request.

![Origin vs Upstream](https://miro.medium.com/max/1400/1*2VsgQel00bwqhvKN8qHNCA.png)

**Remember**: Remotes like `upstream` and `origin` are simply an alias that stores the URL of repositories. They can be named anything, but it’s a convention to set original repo’s remote as upstream.


### Fetch and Pull

**From [Git Documentation](https://git-scm.com/doc)**:

> `git fetch` can fetch from either a single named repository or URL or from several repositories at once.
`git pull` incorporates changes from a remote repository into the current branch.

![fetch vs pull](https://miro.medium.com/max/1224/1*b50bU2iCz4fCf3ZuOn-yfw.jpeg)

`git fetch` is the command that tells your local git to retrieve the latest meta-data info from the original yet doesn’t do any file transferring. It’s more like just checking to see if there are any changes available. `git pull`, on the other hand, git fetch and applies the changes from the remote repository to the local repository.

**Remember**: `git pull` is shorthand for `git fetch` followed by `git merge FETCH_HEAD`.

Putting it rather simply, `git fetch` can be used to know the changes done in the remote repo/branch since your last pull. This is useful to allow for checking before doing a git pull, which could change files in your current branch and working copy and potentially lose your changes, etc.

![fetch vs pull](https://miro.medium.com/max/1216/1*lIGZ2jFMwVcp0-q12Ba2FA.png)

`git fetch` can be helpful in several scenarios, one of them being slightly optimizing your workflow to reduce network hits. Each git pull involves a `git fetch`, so if you want to get a pull on five different branches, you have four redundant extra `git fetch` calls.
Also, `git fetch` can often save you in situations you are working offline or working on the go, maybe on a train, but you want to make sure that you have all the changes from every branch available to you while working remotely. You can simply git fetch once while you’re on the network, and then leave. Later, without a network connection, you can manually `git checkout branch`; `git merge origin/branch` to merge the changes you previously fetched.


### Switch and Checkout

**From [Git Documentation](https://git-scm.com/doc):**

> `git switch` switches to a specified branch. The working tree and the index are updated to match the branch.
`git checkout` updates files in the working tree to match the version in the index or the specified tree.

`git switch` is not a new feature but an additional command to switch/change branch feature which is already available in the overloaded git checkout command. Hence, to separate the functionalities, **Git 2.23** introduced the new `git switch branch` command which is an attempt to start to scale back to the responsibilities without breaking backward compatibility.

![Checkout vs Switch](https://bluecast.tech/wp-content/uploads/2019/09/git_switch_branch_vs_git_Checkout_branch-1024x521.png)

The `git checkout` command operates upon three distinct entities: files, commits, and branches. To put it simply, if you modify a file but haven’t staged the changes, then `git checkout <filename>` will discard the modifications and you would remain on the same branch, while `git checkout <commit hash>` lets you roll back to an older commit, whereas `git checkout <branch>` would switch the branches, hence, to avoid this confusion, `git switch` was introduced.

Below are the three most common use cases of `git checkout`:

![git checkout commit](https://miro.medium.com/max/1276/1*sHJdaHsRpAzCk_ib4x4gCA.jpeg)

![git checkout branch](https://miro.medium.com/max/1276/1*kODKf_nR0rwv3ZOr98cEhg.jpeg)

![git checkout file](https://miro.medium.com/max/1276/1*JwsbBKmfqWuyadWCK275Ag.jpeg)

### HEAD~ and HEAD^

The `~`(tilde) and `^`(caret) symbols are used to point to a position relative to a specific commit. The symbols are used together with a commit reference, typically `HEAD`(represents the current snapshot of a branch) or a commit hash.

![head terminology](https://miro.medium.com/max/1200/1*hxjscRxtC0YpXdNf-9YmoA.png)

- `~n` refers to the nth grandparent. `HEAD~1` refers to the commit’s first parent. `HEAD~2` refers to the first parent of the commit’s first parent.

-`^n` refers to the nth parent. `HEAD¹` refers to the commit’s first parent. `HEAD²` refers to the commit’s second parent. A commit can have two parents in a merge commit.


### Revert and Reset

**From [Git Documentation](https://git-scm.com/doc):**

> `git revert` is used to record some new commits to reverse the effect of some earlier commits (often only a faulty one).
`git reset` resets the current `HEAD` to the specified state.

The `git revert` command is used for undoing changes to a repository’s commit history. It is used to invert the changes introduced by a specific commit and append a new commit with the resulting inverse content. This can be useful for tracking down a bug introduced by a single commit so that it can be automatically fixed by a `git revert` command.

![reset vs revert](https://miro.medium.com/max/1334/1*gwwLoCvrGdTPk6QfX7PZfQ.jpeg)

`git reset` is another complex and versatile git command used for undoing changes, however, `git reset` will move the `HEAD` ref pointer and the current branch ref pointer whereas the `git revert` command doesn’t move the `HEAD` ref pointer.

![git reset](https://i.stack.imgur.com/UWGiw.png)

Putting it simply, if you have already pushed your branch somewhere or someone pulled from your branch, your only option is to `git revert` to undo the changes. Meanwhile, if you have kept your commits entirely local and private, you can simply use `git reset` to undo the changes.

![reset vs revert](https://miro.medium.com/max/1400/1*8q5OTBysupIfkpROkbH_qg.jpeg)


### Merge and Rebase

**From [Git Documentation](https://git-scm.com/doc):**
> `git merge` incorporates changes from the named commits (since the time their histories diverged from the current branch) into the current branch.
`git rebase` reapplies commits on top of another base tip.

![rebase vs merge](https://miro.medium.com/max/1400/1*1C7Rysd6vNCq2DGXaR1zuw.jpeg)

Both of these commands are designed to integrate changes from one branch into another branch, the difference lies in the way they do it. **Rebasing** is the process of moving or combining a sequence of commits to a new base commit while merging ties the histories of both branches and is always a forward-moving change record, hence, doesn’t change the existing branches in any way.
The major benefit of rebasing is that you get a much cleaner project history as it eliminates the unnecessary merge commits required by git merge.

![rebase vs merge](https://miro.medium.com/max/1400/1*s9vhZ0Arc0ViAnl9ksy_Ew.png)

Rebasing works by transferring each local commit to the updated master branch one at a time. This means that you catch merge conflicts on a commit-by-commit basis rather than resolving all of them in one massive merge commit.
Moreover, rebasing makes it easier to figure out where bugs were introduced and if necessary to roll back changes with minimal impact on the project.

> Use this handy [git cheat sheet](https://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet) guide to enhance your workflow.

That’s all for this article. I hope that it would have helped you demystify some of the confusing terminologies related to git and GitHub. Please comment with your valuable suggestions and feedback.
In case you want to connect with me, follow the links below:

[LinkedIn](https://www.linkedin.com/in/pragativerma18/) | [GitHub](https://github.com/PragatiVerma18/) | [Twitter](https://twitter.com/pragati_verma18) | [Medium](https://medium.com/@itispragativerma)