# Git and Github [guide for developers]

If you are a developer, chances are you have heard about git and github or gitlab. If you want to become a developer git is necessary skill that makes your profile astounding. 

### Git is essential for 
* tracking your developer journey
* getting involved in open-source culture
* gaining practical knowledge by contributing to real world projects

So, habituate to git before you close your lid. Make this time to learn git

### Installation & Setup

Install Git from [here](https://git-scm.com/downloads) & [configure](https://stackoverflow.com/questions/68775869/message-support-for-password-authentication-was-removed-please-use-a-personal) with credentials

**Git** (a software): Git is a version control system used for tracking changes used for source code management in software development.

**Github** (a service): Serves as a host for Git repositories to store their code in a centralized location


### Commands

| 	Command	 | 	Description	 |
| 	:-----:	 | 	:-----:	 |
| 	git init	| 	Initializes a new Git repository	|
| 	git add <files>	| 	Adds files to the staging area	|
| 	git status	| 	Used to check the state of the staging area, as well as the working directory |
| 	git log	| 	Used to view the entire commit history	|
| 	git commit -m "message"	| 	Used to commit files (locally) on repository |
| 	git clone	| 	Used to download existing code from a remote repository |
| 	git branch	| 	Used to list all the local branches on the machine  |
| 	git merge <branch-name>	| 	Merges the provided branch with the current working branch  |
| 	git branch <branch-name>	| 	Used to create a new branch locally  |
| 	git branch -d <branch-name>	| 	Used to delete a branch  |
| 	git branch -m <new-branch>	| 	Used to rename the current working branch  |
| 	git checkout <branch-name>	| 	Used to  switch from the current branch to another one |
| 	git push <remote> <branch-name>	| 	Used to  save all commits to the remote repository |
| 	git checkout -b <branch-name>	| 	Create a new branch and switches to the new one  |
| 	git pull <remote>	| 	Used to pull down all the updates from the remote repository  |
| 	git rm <file-name>	| 	Used to remove a file from the  working directory |
| 	git stash	| 	Used to temporarily remove uncommited changes  |
| 	git reset	| 	Undo the changes to the local files and restore to the last commit |
| 	git diff	| 	Displays the difference between files in two commits or between a commit and your current repository  |


### Git Workflow

![git workflow.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1664524404943/zR1Tv2FKI.png align="left")

# Demonstration

## Initializing a new repository

Before you initialize a new repository, first change current directory into the project folder and run the command below

```
git init
```

A git init will initialize your project folder as a Git repository by generating a hidden folder `.git` inside your project folder. This `.git` folder contains all essentials needed for version controlling your new project.

## Status of repository

```
git status
```

Files could be in one of four states

* **Untracked State**: files that are not yet being tracked and managed by git
* **Modified State**:  files that are being tracked and managed by git  and made changes
* **Staged State**: modified files that are prepared to be introduced to git with pending commit
* **Committed State**: files that are already commited.

## Staging files

Staging a specific untracked or modified file
```
git add <filename>
```

Staging all the files in a repo, both untracked and modified files
```
git add .
```
`.` period here represents the project-name 

## Commit files 

```
git commit -m "this is a commit message"
```
`-m` specifies message to the commit which is optional 

---

If you want to work on hosted projects the below are used extensively

## Cloning repositories

use `git clone` to create a copy of the original project which mostly would be hosted on Github, Gitlab or some other cloud code hosting platform.

```
git clone <repository-url>
```

## Creating, listing, renaming & deleting branches

Branching makes it possible to explore other ways to write a functionality without messing with the main code that we implemented or already implementing.

We can create our own branch -> make changes -> open a pull request. Then the project maintainance team would merge our branch to their main branch. This flow open doors for many developers to work simultaneously on a single project.

Creating a new branch
```
git branch <branch-name>
```

Listing all branches
```
git branch
```

Listing [remote branches](https://git-scm.com/book/en/v2/Git-Branching-Remote-Branches) 
```
git branch -a
```

Renaming an existing branch
```
git branch -m <old-branch-name> <new-branch-name>
```

Deleting an existing branch
```
git branch -d <branch-name>
```

Deleting an existing branch even when the branch has not fully been merged in its upstream branch
```
git branch -D <branch-name>
```

## Checking out branches

Checking out is the term used when we change our Git HEAD from one branch to another

Checkout from main branch to a our-branch
```
git checkout <branch-name>
```

Checkout a branch that is non-existent using flag `-b` on git checkout to checkout from your current  branch into a new non-existing branch
```
git checkout -b <new-branch>
```

## Unstagging changes

Often useful

Move every staged files back into your working tree
```
git reset
```

Move only specific staged files back into your working tree
```
git reset <file1>[, <file2>, <file3>, ...]
```

Move only staged files in a given folder
```
git reset <folder-name>
```

## Reset commit history

Often we commit changes that are isn't necessary or done by mistake. In such case we can reser the commit by

`--hard` to delete latest commit
```
git reset --hard
``` 

`commit hashes` can get from `git log` command. Used to reset to a particular commit
```
git reset <commit-hash>
```

## Push local changes to upstream repository

```
git push <remote> <branch-name>
```

eg: `git push origin main`


## Pull changes from the upstream

It is common that local clone diverges or lags behinds the upstream repository in commit history. Without updating local repository with the new commits on the centralized upstream, any pull request we make could result in a merge conflict during merge into the centralized repository.

To resolve this issue we use `pull` to synchronize local repo with centralized upstream.

```
git pull <remote> <branch-name>
```

This cleans up your commit history by removing the common merge commit message
```
git pull --rebase <remote> <branch-name>
```

## Commit history

we can use `git  log` to view commit history

all commit history for a project. 
```
git log
```

commit history from a specific author or committer
```
git log --author <author-name>
```

commit histories having a certain text
```
git log --grep <search-string> 
```

revision history after a specified date
```
git log --after <date-string>
```

revision history between a date range
```
git log --since <date-string> --until  <date-string>
```
---

Experience working of Git by this awesome simulation tool
https://learngitbranching.js.org/

---

Hope this helps and suggest you to use git in regular. Meet you soon with another awesome blog post 😉✍️JrNet
