# Getting to Know Git and GitHub: Your Code's Best Friends

# What is Git?

**Git is a popular version control system**. It was created by **Linus Torvalds in 2005** and has been **maintained by Junio Hamano since then**.

It is used for:

* Tracking code changes
    
* Tracking who made changes
    
* Coding Collaboration
    

Now coming to the definition that you can relate to is that it <mark>allows us to maintain history of the project at what particular time, which person made which change where in the project.</mark>

### Version Control:

Also known as **source control**, is the practice of tracking and managing changes to software code or version control is a system that records changes to a file or set of files over time so that you can recall specific versions later.

### Why Git?

* As I said it's very popular, over 70% of developers use Git.
    
* Developers can work together from anywhere in the world.
    
* Developers can see the full history of the project.
    
* Developers can revert to earlier versions of a project.
    

## Downloading the Git:

[**Download Git**](https://git-scm.com/downloads) from the official website according to your machine.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1694097947171/26c9f27c-82ab-4cfe-bb19-ada95a855fa2.png align="center")

### Confirmation of installation:

```bash
git --version
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1694262406678/0b0d6ee7-52ee-482b-bd8a-01c696c8f7e7.png align="center")

## Configuring git for the first time:

**Set Your Name**:

```bash
git config --global user.name "Your Name"
```

**Set Your Email**:

```bash
git config --global user.email "your.email@example.com"
```

# Some basic Linux commands:

1. <mark>pwd:</mark> Prints the full path of the current directory.
    
2. <mark>ls</mark>: List files and directories in the current directory.
    
3. <mark>ls -a:</mark> It shows the hidden files (those starting with a dot like ".git").
    
4. <mark>mkdir &lt;folderName&gt;</mark>: Creates a new directory with the specified name.
    
5. <mark>touch &lt;fileName.txt&gt;</mark>: Creates a new empty text file with the specified name.
    
6. <mark>cd /path/to/directory or any folder name</mark>: Changes the current directory to the specified path or folder name.
    
7. <mark>clear</mark>: Clears the terminal screen.
    
8. <mark>rm -rf &lt;filename&gt;</mark>: forcefully removes the specified file or directory without confirmation.  
    
    **There are more commands in the beginning, it's enough to know.**
    

---

# Get Hands-on with Git:

### Initializing a Git Repository:

It'll initialize an empty Git repository, repositroy means a folder. Remember that if you haven't initialize a git you just can't proceed further.

```bash
git init
```

### Making the first change:

```bash
touch git_github.txt
```

If you create the above file and make any changes to that file and if you write the command " git status ", you'll see in your terminal that there are Untracked files.

### Staging the first change:

```bash
git add . or git add <Individual file name>
```

So by using the above "git add. or git add &lt;Individual file name&gt;" you will stage that file, and after you stage the file it'll be in the staging area.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1694357452687/28030bc0-fe8b-4c03-8656-a01a7b149c76.gif align="center")

In easy words, suppose you are at a wedding and you have to go on the stage so that your picture is clicked and it is saved(means commit, which under in below point) in the history of the wedding of an album.

### Git status:

<mark>"git status"</mark> basically shows the current status of your Git repository, displaying any changes made to files and indicating which files are staged or unstaged for the next commit.

```bash
git status
```

### Committing the first change:

```bash
git commit -m "I made first commit"
```

So `git commit -m "I made first commit"` you can add any message you want to put after -m in the inverted commas (" "), and now the file of folder whatever you have staged with the "git add . " command now you have successfully saved the changes that you have made.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1694357842692/e2618615-671d-45c7-9b52-ccb829cc31f7.gif align="center")

### Git commit without stage:

Sometimes, when you make small changes using the staging area is like a waste of time. It is possible to commit changes directly skipping the staging environment.

```bash
git commit -a -m " enter you commit message here "
```

### Adding the data to files:

```bash
vi or vim
```

So, to add text to your git\_github.txt file that we've created above you need to use the "vi or vim" command any one of them. After that, you'll enter a text editor and just make some changes there like adding any text you want. Now if you do "git status" again you'll see that the "git\_github.txt" file is modified. And this time you know what to do yes! first "git add ." and then "git commit -m "your message" ".  
To exit out of Vi use this command shift `Esc` then `shift + :` then `q!`  
To save the changes that you have just made in Vi editor press `Esc` then `:wq`  
and it'll save and exit out of that editor.

**<mark>Vi</mark>**: Vi is a text editor commonly used in Unix-based terminal environments.  
**<mark>Vim</mark>**: Vim is an enhanced version of Vi with additional features and improvements.

### Removing changes from the stage:

Let's say you staged a file by mistake and you don't want to commit that changes and you want to remove that so for that you can use this command.

```bash
git restore --staged git_github.txt
```

So I think you understood what's above command doing, It's basically unstaging the file that you have recently staged. And after --staged specify your file name.

### Viewing the overall history of the project:

```bash
git log
```

So after using the "git log" command you can see your history of commits that you have made, You can see below as I attack a photo.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1694356020808/abb544c9-b10f-40ea-bb5a-310735ae49a2.png align="center")

```bash
git log --oneline
```

Display the output as one commit per line.

### Making a few more commits:

So we are making a few more commits and then I'll show you that if we have more commits and we want to remove those commits then how can we do that? Using the below commands:

```bash
git add .
git commit -m " your commit message "

In one line:
git add .; git commit -m "your commit message"
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1694369982174/925e1fcc-5aa0-4dc7-902a-0ad5b08751a4.png align="center")

### Removing the commit from the history of a project:

So now you committed the changes that you have made but you want to remove them for any reason. You have to first copy the commit ID (which you can see in the above image), so whatever commit ID you copy all the commits above it will be removed.

```bash
git reset <commit id>
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1694369976912/d4542514-2a76-4185-9d69-f80c722c5cec.png align="center")

**If you want to delete all the changes in your branch you can do that by this command:**

```bash
git reset --hard <branch name>
```

This can be utilized to stage and unstage the changes. It deletes all the changes made on the current local branch, making it the same as the origin/master, and reset the HEAD pointer. "--hard " is actually reset with hard so do it with caution.

### Stash the changes:

<mark>Git stash temporarily stashes changes you've made to your working copy so you can work on something else, </mark> and then a user can retrieve all files put into the stash with "**git stash pop**" and "**git stash**" commands.

![git stash working, credit: intellipaat](https://cdn.hashnode.com/res/hashnode/image/upload/v1694368469867/ed6812ec-cd0a-4ece-ba86-69030bdcb741.jpeg align="center")

So first, you have to stage the changes that you've made and then you can stash them like sending them backstage and whenever you want them you can bring/ retrieve them. <mark>We are doing this just because you don't want to lose your changes and also don't want to commit it.</mark> A command for that is :

```bash
git stash
```

### See what files are in the stash area:

```bash
git stash show
```

### Popping Stash:

And if you want to retrieve, the command for that is :

```bash
git stash pop
```

### Clearing Stash:

If you want to delete your files that are stored in the stash area the command is:

```bash
git stash clear
```

---

# What is GitHub?

**GitHub** is a platform <mark>an online website that allows us to host our Git Repositories</mark>. A repository is just a folder where all the changes are saved.

Like GitHub, some platforms allow you to host your repository:

* **Bitbucket**
    
* **Gitlab** etc.
    

# Why GitHub?

GitHub simplifies **code collaboration and version control**, **making it easy for teams to work together**, **track changes**, and **share code worldwide**.  
**Hosting and Deployment** means you can host websites and deploy web apps directly from GitHub, simplifying the publishing process.

### Let's see some differences:

<table><tbody><tr><td colspan="1" rowspan="1"><p><strong>Git (Version Control)</strong></p></td><td colspan="1" rowspan="1"><p><strong>GitHub(Code Hosting Website)</strong></p></td></tr><tr><td colspan="1" rowspan="1"><p>Git is maintained by Linux.</p></td><td colspan="1" rowspan="1"><p>GitHub is maintained by Microsoft.</p></td></tr><tr><td colspan="1" rowspan="1"><p>Git is a version control and code-sharing tool.</p></td><td colspan="1" rowspan="1"><p>Used for hosting git repository.</p></td></tr><tr><td colspan="1" rowspan="1"><p>Git was first released in 2005.&nbsp;</p></td><td colspan="1" rowspan="1"><p>GitHub was launched in 2008.</p></td></tr><tr><td colspan="1" rowspan="1"><p>Git is open-source licensed.</p></td><td colspan="1" rowspan="1"><p>GitHub includes a free tier and a pay-for-use tier.</p></td></tr><tr><td colspan="1" rowspan="1"><p>Installed locally on the computer.</p></td><td colspan="1" rowspan="1"><p>Cloud-based.</p></td></tr><tr><td colspan="1" rowspan="1"><p>Track changes made to a file.</p></td><td colspan="1" rowspan="1"><p>Provides a web interface to see the file changes.</p></td></tr></tbody></table>

# Starting Github:

### Creating a new repository on GitHub:

Go to [GitHub's official website](https://github.com/) and make a new repository. Always add "**Readme.md**"  
while creating a new repository. This is how you can create a repository on GitHub.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1694428072021/2af98325-6ec9-4c8e-88cd-9e343d072ac2.png align="center")

**This is the URL of your GitHub repository.**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1694428453707/4c4c3328-6faa-41fb-a606-ed95651c1765.png align="center")

### Connecting Remote Repository to local Repository:

So if you are working on your project with vs code terminal make sure that you are connected to your GitHub account with you vs code. Like this way:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1694429735213/850055b8-1358-4774-bead-fd1331caa15b.png align="center")

So as I told you above the URL of your GitHub repository and now you have to connect your remote repo to your local repo. So, to do that here is the command:

```bash
git remote add origin <your github repository url here>
```

**<mark>remote</mark>**: remote here means that you are working with URLs like here with the GitHub repository URL.  
**<mark>add</mark>**: add basically means you are adding a new URL.  
**<mark>origin</mark>**: origin means that what is the name of the URL that you are going to add. origin is the default name here but you take any name of your choice.

**For checking which URL you working with, the command for that is :**

```bash
git remote -v
```

**<mark>remote -v</mark>** : `git remote -v` is the verbose(-v) version of this, that is, it shows the names of the URLs along with the URLs.

**If you want to remove the URLs that you have added, the command for that is :**

```bash
git remote rm <name of the url >
```

**<mark>git remote rm &lt;url-name&gt;:</mark>** deletes a named remote URL from your Git project.  
A local git repo can have any number of remote URLs, just make sure that names are unique. Remote URLs are nothing but GitHub repo links as I told you above.

### Pushing local changes to the remote repository:

So now you have staged and committed (saved) your changes to a particular file or folder. You have connected your remote repo with the local repo. Here we are pushing the local repository to our remote repository. The command for that is :

```bash
git push origin <branch name>
```

**<mark>push</mark>**: means just push the changes.  
**<mark>origin</mark>**: name of the URL.  
**<mark>branch name:</mark>** The default name of every GitHub repository is 'main' but you can take any name of your choice of your branch.

### What are branches?

In Git, **a branch is a new/separate version of the main repository.** **Branches allow you to work on different parts of a project without impacting the main branch.** When the work is completed, a branch can be merged with the main project which we'll loop more into in the merging the branch concept.

### Use of branches like why we have branches:

The use of branches is that whenever you are working on a new feature or resolving bugs or whatever always create a new branch. So as I told you the "main" branch is the default one and this main branch code is being used by people like the users and the developers. We should never commit directly to the main branch because our code is not yet finalized, it might contain some error or we also don't have access to directly commit the changes to the main project.

### Git branching:

**Making a new branch and switching to it:**

```bash
git branch <name of the branch>
```

**Checking all the available branches:**

```bash
git barnch
```

**Switching to the created branch:**

```bash
git checkout <branch name>
```

**Making a new branch and directly switching to it:**

```bash
git checkout -b <branch name>
```

**Deleting a branch:**

```bash
git branch -d <branch name>
```

**Merging branch to main:**

```bash
git merge <branch name which you want to merge into main>
```

**Rebase command:** When we are rebasing branches, we are basically putting one branch on top of another one. When we rebase branches, however, we are actually copying the commits from one branch to another. Since we are creating new copied commits, the hashes update. In other words, we are modifying the Git history when we are rebasing the branch. Although this is not always a problem, it can annoying when you are working with a team. It's not clear when certain branches got rebased since there is no merge commit.

```bash
git rebase <branch name>
```

You can play with branching here by [**learngitbranching**](https://learngitbranching.js.org/)

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1694436166930/41691241-6ed9-4999-8c6d-2ab263e10301.png align="center")

### Understanding the ".git" folder:

The ".git" folder is created when you run `git init` command in your terminal. Let's understand what's inside the ".git" folder.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1694430955327/4d9b7ec2-1582-494a-82c2-141d33dd7939.png align="center")

**<mark>HEAD</mark>**: **The head is just a pointer that points to the current branch** that means if your head is pointed to the master branch all the commits you are making will be added to the master branch.

**<mark>config</mark>**: The **repository-specific configuration settings** are stored here.

**<mark>description</mark>**: A simple text file describing the repository.

**<mark>hooks</mark>**: This directory **allows you to set up custom scripts that Git can run at certain events**, such as **pre-commit** or **post-merge**.

**<mark>info</mark>**: It contains some **global configuration files**.

**<mark>objects</mark>**: This directory stores all the **data objects, including the commits, trees, and blobs (file contents), in a compressed format.**

**<mark>refs</mark>**: Here, **Git stores references to branches, tags, and other commit pointers.**

### Pushing new changes to the branch:

So if you use the below command you are pushing your changes from the local repository to the remote repository.

```bash
git push origin <branch name>
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1694436764122/80ef798c-45ab-4289-b29f-9866a1d5782c.png align="center")

### Working with Existing Projects:

**Instruction on how to try doing these on your own:**

Working with existing projects is a hands-on practice to learn about Git and GitHub more practically. I have provided you with the [Getting-started-with-Git-Github](https://github.com/Suraj-kumar00/Getting-started-with-Git-Github) repository Just play with this repository. Fork it, clone it, make changes, make a branch, do try all the commands, I mean do whatever I've told you in this blog and you'll get hands-on experience. Do all this and create a new pull request and I'll merge it.

### What is a fork, why to fork, and how to fork?

**<mark>What is a fork</mark>**: A **fork** is a **copy of a Git repository hosted on a platform like GitHub**, a fork is created by someone other than the original repository owner.

**<mark>Why to fork:</mark>** People fork repositories to :  
**To Contribute**: Forking allows you to make changes to a project without affecting the original.

**To Experiment**: You can freely experiment with the code or project without worrying about breaking the original.

**<mark>How to fork:</mark> Go to the Repository**: Visit the repository you want to fork on a platform like GitHub.

**Click "Fork"**: Click the "Fork" button on the top-right of the repository's page. This creates a copy of the repository under your GitHub account.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1694443271108/77a219bc-3782-4e02-aedf-3088aa52d9f3.png align="center")

### The primary stages in Git are:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1694353736261/1022e12c-75e7-4cc7-bd8f-c5b770d98046.png align="center")

***Explaining the above Image: So now you know what is***  
***<mark>"Remote Repository"</mark>: This is hosted on GitHub or on any server of which you have a URL.***  
***<mark>"local repository"</mark>: The repository which is in your local machine.***  
***<mark>"staging area"</mark>: An area where you have staged your changes.***  
***<mark>"working directory"</mark>: It's a folder/directory where you are currently working you your project.***

### Cloning the forked project to the local system:

To clone any repository first you have to fork it as I told you above and then use `git clone` it to download your fork to your local machine. Remember that copy the URL of the forked repository to clone it.

```bash
git clone <url of the forked repository>
```

### What is Upstream and adding it to the local system:

The "Upstream" refers to the original or main repository of a project from which other copies or forks are made. <mark>And coming to the URL part the upstream is the name of the original repository's URL </mark> as we know that the origin is the name of the remote repository" 's URL of your own account.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1694435113434/eeae24be-726d-4388-b398-6ba908d3ec11.png align="center")

**To add the upstream or origin URL means the remote repository to the local, the command for that is:**

```bash
git remote add <link remote repository>
```

### What is a Pull Request?

**When you create your own copy of another's project or repository** and you make any changes in your copy then **how do you make sure whatever changes you've made are visible in the main branch/project?** So for this, <mark>you request/create a new "</mark>**<mark>pull request</mark>**<mark>". Then people or maintainers of that particular project will review your code, and suggest some changes You'll make those changes and when this is merged whatever changes to any feature you've added will be visible in the main project's main branch.</mark>

### What is a draft pull request?

**A draft pull request is like a work-in-progress version of a pull request**. It's not ready for final review and merging, but <mark>it allows you to share your changes with others for early feedback and collaboration before completing it</mark>. Draft pull requests are useful when you're still making changes and want to keep the discussion separate from a fully finished pull request.

### Never commit on the main branch & create our first pull request:

You should never commit to the main branch because you don't have access to the upstream branch so how can you do that? So always create a separate branch and create a new pull request to merge your changes into the main branch.

After making changes in your branch you can create a new pull request and your master branch changes will be merged into the main branch of the repository.

If a branch already has a pull request associated with it'll not allow you to create a new pull request.

**<mark>"One pull request means one branch"<br>"One branch can only open one pull request"</mark>**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1694450219397/3d4b1c5e-6f90-4806-aced-7cd1944a7e0d.png align="center")

### Removing a commit from the pull request by force pushing to it:

For that first, you have to clear commits to your local repository.

```bash
git reset <commit id>
```

And then stage the changes and stash them:

```bash
git add . 
git stash
```

**Force push the changes to the branch:**

And now you have to force push this because an online repository contains commits that your local repository does not.

```bash
git push origin <branch name> -f
```

### Merging a pull request:

As you can see in the below image after clicking on the "Merge pull request" all the changes that you've made in your local branch now they are now reflected in the main branch.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1694450214357/265c915a-8c4a-4180-b9bf-e5826a26a6aa.png align="center")

### Making a forked project updated with the main project:

In your local repository first, you've to check out the branch that you want to update with the remote repository and then apply these commands.

Step 1:

**To fetch all changes or commits:**

```bash
git fetch --all --prune
```

So "prune" basically means here that the ones that are deleted will also be fetched.

Step 2:

Reset the main branch of my origin to the main branch upstream.

```bash
git reset --hard upstream/main
```

here you can write the name of the upstream branch in the above command. Now your local repository is up to date with the remote repository.

**You can also do this by pulling the changes below I've explained.**

### Pull the changes from the Remote Repository:

If you don't want to do this you can first pull the changes from the remote repository to the local repository and then push the changes to the remote repository. `git pull` command does two things at once which are `git fetch` and `git merge` .

```bash
git pull origin <branch name>
```

So origin means that you want to fetch the changes to the local repository from your own GitHub repository.

```bash
git pull upstream <branch name>
```

So upstream here means that you want to fetch change from the upstream branch whose repository owner is someone else and you have forked that repository on your GitHub account.

### Squashing commits:

Squashing commits means you are combining multiple consecutive commits into a single commit with a concise commit message.

One way we know that if we have more commits, we just need to reset it and commit again with the single message but here we are going to try something different.

You can also do that using the **rebase** command which is below.

### Using the Rebase command:

```bash
git rebase -i <commit id here>
```

" -i " here means 'interactive environment'. After entering this command you'll enter an interactive environment and after that you see there are lots of commands and "pick" and "s" You'll see these two with hash id(commit id). After entering the interactive environment you have to press "i" to make any changes/manipulation.

P, pick &lt;commit&gt;: In the pick, all the commits will be merged.

s, squash &lt;commit&gt;: Squash is used to merge into the previous commit

Now I've attached the two images so you can better understand this or by doing it on your own.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1694487931688/8b686115-b49c-4109-b68f-70da7392f6cc.png align="center")

After you do `shit` + `:x` **you'll enter in the below editor where you can write your single commit message.**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1694487950810/b65ddd25-badd-4f62-bfe4-4f74bc70606f.png align="center")

And now you are done with squashing your commit using the rebase command.

### Merge conflicts and how to resolve them:

In a file let's say you made a change in line number 2 and someone also made a change in line number 2, Now git will get confused about whether should I take yours or someone else changes so git will ask you for help that you want to take this change of that change.

It occurs also when one person edits a file and another person deletes the same file.

**How to resolve a merge conflict:**  
You have to resolve it manually.

---

***What to do next:***  
***I think this is more than enough for a beginner even if you want to contribute to*** [***open-source***](https://surajk00.hashnode.dev/what-is-open-source-beginners-guide-how-to-get-started)***. In the end, I just want to say that whatever I have explained in this blog do hands-on practice otherwise you'll not be able to understand it.***
