# A Simple Git Help

A simple tutorial for understanding Git basics.

## So, What is Git?&#x20;

Git is a Source Control (sometimes it is also called Version Control). Source control is the process/practice of tracking and managing changes to software code. Source control is specifically for source code, whereas Version control is for versioning all types of data, not just for source code, ex:- versioning images, documents, binary data etc. For better understanding check this [BitBucket tutorial](https://www.atlassian.com/git/tutorials/what-is-version-control).

Another explanation from[ AWS](https://aws.amazon.com/devops/source-control/git/) "Git is an open-source distributed source code management system. Git allows you to create a copy of your repository known as a branch. Using this branch, you can then work on your code independently from the stable version of your codebase. Once you are ready with your changes, you can store them as a set of differences, known as a commit. You can pull in commits from other contributors to your repository, push your commits to others, and merge your commits back into the main version of the repository".

The whole concept of version control is to let multiple developers work on a single project. So there is a git central system (git remote repository ex:- github, gitlab, etc) where the project source is stored. And each developer will move their code from their local computer to the remote git repository (git server) and also pull code pushed by other developers from remote repository to their computers.

{% hint style="info" %}
&#x20;To connect from your computer to this remote repository you will  need[ git client](https://github.com/git-guides/install-git) on your computer. There are few GUI clients as well, but we will only cover the command line CLI here. You can install [git client from here](https://github.com/git-guides/install-git).
{% endhint %}

## Git System Architecture

**This is the most important step in understanding git.**

Most of the other version controls before Git worked as follows.

As a developer you will write code using code editors like Notepad, Eclipse, etc., save those files (.js .py .java .html etc., files) in your local computer and then move those to the remote source server. This is true for git as well but there are a couple more steps with git.

‌Unlike other version control systems Git structures data into 4 areas, the first 3 of these are on your local computer and the last "Remote Repository" resides in the remote server.<br>

Working Directory --->  Staging(or Index) ---> Local Repository  =============> Remote Repository

{% hint style="info" %}
Working directory is the file system where you edit files using Visual Studio Code/Notepad or other IDE's.
{% endhint %}

![](/files/-MgetKSFFt2DsUr9bKo4)

To visualize, you can think of these as 3 different folders. Working Directory is the only thing which is accessible to edit with your editors like Visual Studio Code or notepad etc. Staging (also called Index) is another folder and 'Local Repository' is yet another folder (Staging and 'Local Repository' are hidden).&#x20;

Now lets say you implemented a new feature called 'image compress' and for this new feature you created/modified two files, lets say these files are ImageComp.java, Util.java. To send your code to remote git reposity you need to do the following.&#x20;

#### Step -1:  You will select these two files and add it to staging area.&#x20;

{% hint style="info" %}
**Staging is like a basket (Imagine you are going to a shopping mall where you pick different items and put them into your shopping cart).**&#x20;
{% endhint %}

```
# And this is how you to add ImageComp.java, Util.java files to 'Staging Area'

git add ImageComp.java Util.java
```

#### Step-2:  Then you move your code from **Staging Area** to the **Local Repository** (Remember you are moving your code to the to the local repository not to the remote repository).

And while you are moving your code to the local repository you can write a note about the changes. For example for the above commit you can say "code for image compression". Later when you are looking at git history and try to understand what these commits are for, this commit label helps you and other devs to quickly understand these changes. It's a good practice to give a brief and high level description for each commit.

```
# This is how you move your code from 'Staging Area' to your own 'Local Repository'
# Note:- This command not moving your code to remote git repository.

git commit -m "code for image compression"
```

> With this commit action both of these files are grouped together and given a label called 'code for image compression'.&#x20;

**Step-3: Once you label your code changes and add it to the Local Repository now is the step to move that commit to the Remote Git Repository.**

```
# This is how you push your local code (commit) to the remote git repository

git push origin master
```

{% hint style="info" %}
I will repeat the above steps again, because you need to understand these steps well. Your local repository is not the same as your working directory. So when you write code and save, it will be saved in your working directory. Then from that working directory, you will add selected files into the 'Staging' area. From the staging area you will move your code to your 'Local Repository'. Remember at this step all these changes happen only inside your computer. Code is not moved to the remote git repository. Only when you do push action, your code is moved from your local repo to remote repo.
{% endhint %}


# Basics

Commands and their purpose for basic git operations

### Git Clone

When you clone a remote git repository, that remote code is copied into your 'Local Repository' and also it is copied into your 'Working Directory' (Staging area is empty for freshly cloned projects).

### Git add

After you modify your local files, to add them to Staging area.

```
git add file1.java file2.java
git add *
```

{% hint style="info" %}
You can add all files with \* ex:- git add \*
{% endhint %}

### Git Commit

To move the currently staged files into local repository. You can also label the current commit with a description.

```
git commit -m 'image compression module'
```

### Git Push

To push your local repository changes to the remote git repository(on remote git server).

```
git push origin master
```

### Git Pull

Git pull will fetch the remote git code (from git server) to the local git repository and also merges those files to your working directory. You will most frequently use 'Git Pull' over 'Git Fetch'.

Git Pull = Git Fetch + Git Merge

```
git pull
```

### Git Fetch

To pull other developers code from the remote git repository to the local repository. Git fetch wont merge these freshly fetched files files into 'Working directory'. Check 'Git Pull'.

```
git fetch origin
```

### Git Merge&#x20;

You want to merge the code which is in the local repository to your working direcotry

You may wonder why will your code in your local repository different to your working directory. This happens when you pull code from the remote repository, that will be moved from remote to local repository and then into your working directory.

```
git merge
```

{% hint style="info" %}
A good tutorial on git merge <https://www.atlassian.com/git/tutorials/using-branches/git-merge>
{% endhint %}


# Git Branching

What is brancing?

Imaging you released a web app project for production, where your customers are using it. And you started working on a next feature enhancement. Now lets say a user found a major bug in the production app, which needed to be urgently fixed. You have to keep aside the feature enhancement code and start immediately on the production bug.  This is called branching, git branching allows you to work in parallel on multiple features or branhes of the same project.&#x20;

The work-in-progress implemented feature code is a separate branch and the production code is a separate branch. You can quickly jump to production code fix that critical bug, push it to production branch and then jump back to the feature enhancment you were working on. When you started working on your feature enhancment code, you made few changes to the files, added new files etc. But the moment when you switch to production branch, all those modified files and newly added files in your **working directory** are kept aside and the working directory is replaced with the production code( the newly created files for that feature are not any more visbile). Your current code is the production branch code, the code you kept aside is feature-branch. Git allows you to work on multiple branches, you can name the branches as you like.

{% hint style="info" %}
If you create a branch in your computer, it wont be automatically pushed to the remote branch. You have to push that new branch to the remote git repository.
{% endhint %}

Its very easy to create a new branch with git.

```
git branch new-branch-name


```

{% hint style="info" %}
Very important: When you create a new branch like above, your working-directory is not automatically switched to the new branch. For that you have to type

```
git checkout -b new-branch-name
```

{% endhint %}

{% hint style="info" %}
Generally for each feature you will create a separate branch and start working on it.

And before you push your code to remote branch, you will pull the latest changes from the remote + merge changes(if there are any changes by other devs) and then push to remote.
{% endhint %}

#### Scenario-1 : Lets take a scenario of how you will work on a short feature (mostly as a individul dev).

Imagine this scenario, you are on main branch ( previously use to be called master branch). You started working on a feature called 'password-check'.  This is how you will work.

Step-1: You will pull the latest main/master branch code from the remote repository.

```
git pull 
```

Step-2: Create a new branch from the main/master, lets call this new branch password-check

```
git checkout -b password-check
```

This above command will create a new branch called 'password-check' which is a copy of the current main/master branch.

Now you will open your IDE like Visual Studio Code and start working on the password checking feature on the password-check branch. **All your code changes are in the password-check branch.**&#x20;

You will add the modified files or newly added files (git add) and git commit those changes to the password-check branch.

Once you make all the changes required for passowrd-checking and commited them to the password-check branch. You will pull the latest main/master code from the remote repository (this is required because other devs may have pushed some changes ).

```
git checkout main
```

With the above command your working directory is switched to main branch. All your password-check branch code is saved (assuming you commited that code) and it is replaced with the main branch code. You wont see your password-check files in main branch, because they are in different branch, you have to merge the password-check branch changes to the main branch with the following command.

```
git merge password-check
```

&#x20;Now main branch is also have the password-check branch code. At this point you will generally push your changes to remote git(but you need to do a git pull before you push to get other devs code).&#x20;

Once all these steps are done, you don't require the password-check branch, which you can delete with the command.

```
git branch -d password-check
```

The above working style is typically used with individual developer. But when you working in a organization with a team of devs, you will typically create a pull requests (please check the next chapter for Pull Requests).


# Pull Request

In progress.....


# Submodules

Imagine a situation where you want to include a project/code(lets call it Project-Common-Code) into two separate git projects(Project-A and Project-B).  You can easily copy the Project-Common-Code into Project-A and Project-B, but everytime the Project-Common-Code is updated you have to copy that again to Project-A and Project-B. You may also face merge issues if you modify them. To avoid such situations you can make the Project-Common-Code as a submodule inside the Project-A and Project-B. And you can independently modify that project and pull them into Project-A and Project-B.


# Commit changes to other branch

You can commit changes in different types.

#### Type 1:

```
git stash
git checkout otherBranch
git stash pop
```

#### Type 2:

```
git branch otherBranch
git checkout -m otherBranch
```

#### Type 3:

```
git checkout otherBranch
git add *
git commit -m
```

[`https://stackoverflow.com/questions/2944469/how-to-commit-my-current-changes-to-a-different-branch-in-git`](https://stackoverflow.com/questions/2944469/how-to-commit-my-current-changes-to-a-different-branch-in-git)


# git log

To see the git commit logs

To list down the previous commit logs

```
git log
```


# git status

To find what is the current status of your git repository, how many files are commited to local repo, what is the current branch etc.

```
git status 
```

&#x20;


# git init

'git init' will make the current directory/folder to git repo, which means you can link the current folder to a remote git hosting provider like GitHub.com, GitLab.com , BitBucket etc.

```
// Run this command inside the folder
git init
```


# Amend a commit

To modify an existing commit

### Git Amend

Lets say you commited your code to local repository and later you found you want to add or modify that commit, you can use git amend.&#x20;

```
git commit --amend
```

> Note:- this amend works only for the local git commit which is not yet pushed to remote repo.

git rebase --continue


# Reset a file or full

To reset a file to the original file

To reset a file to its orginal file (remove your changes to the file abc.txt)

```
# With Git 2.23
git restore abc.txt  

# With older version of git
git checkout -- abc.txt
```

To do full reset a file (reset the file back to original remote format)

```
git checkout @ -- abc.txt

git checkout HEAD -- abc.txt
```

{% embed url="<https://stackoverflow.com/questions/7147270/hard-reset-of-a-single-file>" %}

### **To reset a local branch exactly to the remote**&#x20;

```
git fetch origin
git reset --hard origin/master
```


# Undo git add

How to undo/remove file after  'git add'

Lets say you mistakenly added a file using the following command.

```
git add abc.txt
```

To undo adding run the following.&#x20;

```bash
git reset HEAD abc.txt
```

**Dont do git reset, you will loose changes**&#x20;

```bash
git reset abc.txt    < ---- DONT DO THIS
```

<https://stackoverflow.com/questions/348170/how-do-i-undo-git-add-before-commit>


# Get remote repo url

How to get remote repository url

To get remote url run

```
git config --get remote.origin.url
```

To get all the remote details

```
git remote show origin
```

For more details check <https://stackoverflow.com/questions/4089430/how-can-i-determine-the-url-that-a-local-git-repository-was-originally-cloned-fr>


# Add or Set Remote URL

To add a remote repository to a existing git project or to update the existing rep

Note:- You can create a local git repo with "git init" command. Then you wont have the remote repository set. In that case you can add a remote repository with the following command.

```
git remote add origin https://github.com/USERNAME/REPOSITORY.git
  -- or --
git remote add origin git@github.com:USERNAME/REPOSITORY.git
```

If you want to change the url of an existing remote repository:

```
git remote set-url origin https://github.com/USERNAME/REPOSITORY.git
  -- or --
git remote set-url origin git@github.com:USERNAME/REPOSITORY.git
```

To find remote repo&#x20;

```
git remote -v
```

<https://stackoverflow.com/questions/42830557/git-remote-add-origin-vs-remote-set-url-origin>


# delete branch

To delete a local branch

```
# To delete local branch (which is not there in server)

$ git branch -d <branchname>
```

To delete a remote branch

```
# To Delete Remote branch

$ git push -d <remote_name> <branchname>
$ git push -d origin <branchname>
```

<https://stackoverflow.com/questions/2003505/how-do-i-delete-a-git-branch-locally-and-remotely>


# Other good links

Some good articles, tutorials on Git.

## [Git Cheatsheet](https://training.github.com/downloads/github-git-cheat-sheet/)

#### <https://www.atlassian.com/git/tutorials/learn-git-with-bitbucket-cloud>

#### A nice explaination of git <https://eagain.net/articles/git-for-computer-scientists/>

#### Another nice article on Git by Robin Wieruch <https://www.robinwieruch.de/git-team-workflow>

{% embed url="<https://dev.to/lydiahallie/cs-visualized-useful-git-commands-37p1>" %}

### To pracitice

#### [try.github.io](https://try.github.io/)

#### [git-school.github.io/visualizing-git](http://git-school.github.io/visualizing-git/)

#### [learngitbranching.js.org](https://learngitbranching.js.org/)


# Credits

Git-help.com is built and hosted on [Gitbook.com](https://www.gitbook.com/?utm_source=content\&utm_medium=trademark\&utm_campaign=prakis) Thank you Gitbook.

Icons by [uxwing.com](https://uxwing.com/dedicated-hosting-server-icon/), [reshot.com](https://www.reshot.com/free-svg-icons/item/list-UQ7FKRE2YS/)

by Kishore [@prakis](https://twitter.com/prakis)


