Git Cheatsheet
Tags: webdev, beginners, git, github
Published: 2023-03-14 18:48:30

After completing my third group project at my coding bootcamp, I felt like the thing that frustrated me the most consistently for the last three weeks was using git/GitHub. Too many times had I resorted to nuking my local repo and re-cloning the remote, totally missing the purpose of git. 

_All terminal examples are started in an empty git repository._

# Terminology

- **index**: The Git data structure called the index (also known as the staging area or the cache) is a file that contains a list of other files for Git track. Running `git add` updates this index file with the new changes, but does not yet add the changes to the commit history. 

- **HEAD commit**: The commit that is currently checked out. Running `git commit` or `git checkout <commit-hash>` will move the head to the relevant commit. 

- **Working tree**: The set of files and directories that make up the project on the user's local machine. This is distinct from the index file, as the working tree can contains files not tracked by Git.

# Staging

## git status
Displays paths that have differences between the index file and the current HEAD commit, paths that have differences between the working tree and the index file, and paths in the working tree that are not tracked by Git.

```
touch main.txt
git status
```
returns
```
On branch main

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        main.txt

nothing added to commit but untracked files present (use "git add" to track)
```

## git add

### git add [file]

Updates the index with the given file.

```
touch main.txt
git add main.txt
git status
```
returns
```
On branch main

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   main.txt
```

### git add .

Updates the index using the current content found in the working tree. Write '.' in place of the file to add all changes.

```
touch main.txt
touch not_main.txt
git add .
git status
```
returns
```
On branch main

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   main.txt
        new file:   not_main.txt
```

## git commit -m '[commit message]'
Adds the staged content in the index file as a new commit snapshot. This will be accessible later and will not be at risk of being deleted or overwritten. Unless, of course, you want to delete/overwrite commits!

```
touch main.txt
git add .
git commit -m 'add main.txt'
```
returns
```
[main (root-commit) 85cc587] add main.txt
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 main.txt
```

## git reset

### git reset [file]
Removes the given file from the index. Opposite of `git add [file]`.
```
touch main.txt
git add main.txt
git reset main.txt
git status
```
returns
```
On branch main

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        main.txt

nothing added to commit but untracked files present (use "git add" to track)
```

### git reset [commit]
Removes all commits after the given commit and leaves the working tree in it's current state.

```
touch main.txt
git add main.txt
git commit -m 'add main.txt' 
    # commit hash: 65cd652 
touch not_main.txt
git add not_main.txt
git commit -m 'add not_main.txt'
git reset 65cd652
git status
```
returns
```
On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        not_main.txt

nothing added to commit but untracked files present (use "git add" to track)
```
and `ls` returns
```
main.txt  not_main.txt
```

### git reset --hard [commit]
Removes all commits after the given commit and updates the working tree to match the given commit.

```
touch main.txt
git add main.txt
git commit -m 'add main.txt' 
    # commit hash: d996f35
touch not_main.txt
git add not_main.txt
git commit -m 'add not_main.txt'
git reset --hard d996f35
git status
```
returns
```
On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        not_main.txt

nothing added to commit but untracked files present (use "git add" to track)
```
and `ls` returns
```
main.txt
```

# Comparison

## git diff

### git diff
Show changes between the working tree and the HEAD commit.

```
touch main.txt
git add main.txt
git commit -m 'add main.txt'
echo 'some text' >> main.txt
git diff
```
returns
```
diff --git a/main.txt b/main.txt
index e69de29..7b57bd2 100644
--- a/main.txt
+++ b/main.txt
@@ -0,0 +1 @@
+some text
```

### git diff --staged
Show uncommitted changes in the index file.

```
touch main.txt
git add main.txt
git diff --staged
```
returns
```
diff --git a/main.txt b/main.txt
new file mode 100644
index 0000000..e69de29
```


`git diff --cached` _is an alias of_ `git diff --staged`

### git diff [branch_A] [branch_B]
Shows changes between the two given branches.

```
git checkout -b branch_A
touch file_A.txt
git add .
git commit -m 'file_A'
git checkout -b branch_B
touch file_B.txt
git add .
git commit -m 'file_B'
git diff branch_A branch_B
```
returns
```
diff --git a/file_B.txt b/file_B.txt
new file mode 100644
index 0000000..e69de29
```

Resources: 
[1] DZone - Top 20 Git Commands With Examples - https://dzone.com/articles/top-20-git-commands-with-examples
[2] git - git documentation - https://git-scm.com/doc