Git Repository Essentials
Tags: git, repository
Published: 2022-10-16 19:44:58

# Theory
Git-repository is a collection git-branches
## Sections / Areas in git-branch
There are primarily 5 sections / drives / spaces in every git-branch
1. Working Area: Any file you create or modify included automatically in working area
1. Staging / Index Area: Area where you temporarity save your current changes. 
1. Stash Area: stack of temporary-changes. Storeas changes you want to remove now from file but want to include it later on. You need to use it mostly when two or more developers working on a same branch and you want to include changes from all of them one after another
1. Commit Area: contains stack of commits. Each commit is snapshot of code at the time commit is created. Save your changes permanently in git.
1. Remote Area: Backup / Sync your Commit Area on a remote server like Github or Bitbucket

```
Working Area <-> Staging Area
Working Area Staging Area -> Stash Area -> Working Area
Staging Area <-> Commit Area
Commit Area <-> Remote Area
```


# Practical

### Notes:
1. Refere all git commands using `git --help`
1. You can replace `<file_path>` with `.` in the following code to apply command on all files

### Create and Delete git-repository
```sh
git init # create first branch (master-branch) in current folder and move all your files in working area

rm -rf .git  # remove all git drive / sections
```

### Git Configuration
There are two git configurations - Global (default for new repository) and Local (for current repository)
```sh
# use --global flag, to update gobal-configuation file
git config -l   # list global and local git config
git config -e  # update local git-config file which is present at ".git/config"
git config user.name "John Doe" # update User/Author name
git config user.email johndoe@example.com
git config core.editor "code --wait"	# set vs-code default editor for git
git config core.editor "nano -w"       # set nano as default editor for git
```

### Working Area
```sh
git status # see which files / changes present in which area # file-names in red color are in working_area
# file-names in green color are in staging_area

git diff <file_path> # see changes present in working-area
git restore <file_path>   # delete file-changes made working area
git clean -f # delete all files in working area
git clean -fd  # delete all files and directories in working area
```

### Staging / Index Area
```sh
git diff --staged # see changes in present in staging_area
git add <file_path>   # move changes (newly created files or modification in previous files) to staging area
git restore --staged <file-path>   # move changes from staging_area to working_area
```

### Stash Area
```sh
git stash # move all changes from working and staging area to stash_area
git stash list # list all blocks of temporariy changes
git stash pop  # move most-recent block from stash_area to working_area ( position{0} )
git stash clear # delete all blocks in stash
```

### Commit Area
```sh
git commit -m '<message>'     # move changes from staging_area to commit_area
# <message> is short text giving information about changes made in the commit
git commit --amend -m '<message>'  # move from staging_area to commit_area, but replace last-commit instead of creating new-commit
git log  # view all commits in current branch
git log --oneline # view all commits without description
git log --oneline --graph --all	 # view graphical representation of all branches
git diff <commit_id> # view changes present in commit_id

git revert <commit_ID> # remove all changes in given 'commit_ID'
git reset HEAD~1  # delete last commit and move changes from last-commit to working-area
# HEAD~2 will delete latest 2 commits, HEAD~3 will delete latest 3-commits and so on..
```

### Remote Area
```sh
git remote add <remote_area_name> <remote_area_url> # add connection to the remote_area
# you can give any name you want to remote_area_name, devlopers normally use "origin" for their first / default remote_area
git remote -v  # list currently set remote_area / servers names and their areas
git remote remove <remote_area_name>   # remove connection with remote repository
git push <remote_area_name> <branch-name> # copy changes in commit-area to remote_area
git fetch <remote_area_name> <branch_name> # copy branch remote_area to commit_area
git pull <remote_area_name> <branch_name> # merge remote branch to current branch
git clone <remote_area_url> # copy git repository from remote server/area to current folder

# for https-url
git config --global credential.helper cache   # save github password so you don't have to type it again
git config --global --unset credential.helper  # remove cached credentials
```

### Branch Management
```sh
git branch <branch-name> # Create a new branch containing all git commits of current git-branch
git checkout --orphan <name>  # create a fresh branch without commits from current-branch
git branch -d <branch-name> # delete branch
git branch -m <current-name> <new-name>  # Change branch name
git checkout <branch-name> # move to another branch
git branch --all  # list all local and remote branches

git merge <branch-name> # merge branch with  <branch-name> to current branch
git merge <branch-name> --allow-unrelated-histories  # merge branch whose git-history does not match with current branch, normally used to merge changes from another repository
git merge --abort   # stop current merge process if there are conficts in merge, and you don't want to resolve them now
```

### Git Tags
```sh
git fetch --all --tags  # fetch all tags from remote
git checkout tags/<version> -b <branch-name>  # switch to a tag and create bracnh for it
```