# Git
## Configure
``` git
git config --system <configuratoin>
git config --global <configuratoin>
git config --local <configuratoin>
```
### Alias
``` git
[alias]
st = status --short
lg = log --oneline --graph
co = checkout
```
## Initialize
``` git
git init
```
## Ignoring Files
- \# \- comments
- /XXX \- avoid recursively
- XXX/ \- specify a directory
- ! \- negate a pattern
``` git
# ignore all .a files
*.a
# but do track lib.a, even though you're ignoring .a files above
!lib.a
# only ignore the TODO file in the current directory, not subdir/TODO
/TODO
# ignore all files in any directory named build
build/
# ignore doc/notes.txt, but not doc/server/arch.txt
doc/*.txt
# ignore all .pdf files in the doc/ directory and any of its subdirectories
doc/**/*.pdf
```
## Snapshot Changed Files
Files in your Git repository folder can be in one of 2 states:
- **Tracked** - files that git knows
- **Untracked** - files that git doesn't know
### Add Files into Staging Area
``` git
git add <file or path>
git add --all / git add -A
```
### See the status of files
``` git
git status
```
``` git
git status --short
```
- ?? - Untracked files
- A - Files added to staging area
- M - Modified files
- D - Deleted files
- R - Renamed files
### Commit Files in Staging Area to Repository
``` git
git commit
git commit -m "message"
```
### Check the information of each commits
``` git
git log
# comppressed SHA-1 and graph
git log --oneline --graph
# specify a file
git log -- <file>
# show patch of each commit
git log -p
# limit the number of commit
git log -<number>
# specify a function
git log -S function_name
# show all branch
git log --all
```
## Undo
### Commit Amend
Commit and overwrites the previous commit
``` git
git commit --amend
```
### Unstaging a Staged File
``` git
git restore --staged <file>
git reset HEAD <file>
```
### Unmodifying a Modified File
``` git
git restore <file>
git checkout -- <file>
```
## Diff
``` git
# comparing working tree with staging area.
git diff
# comparing staging area with last commit.
git diff --staged
# comparing working tree with last commit.
git diff HEAD
# check possible white space errors
git diff --check
```
## Another way of specifying commit_id
``` git
HEAD~0
```
Indicates the newest commit
``` git
HEAD~1
```
Indicates the commit before the newest commit
## Go back to a specific commit
``` git
git reset --mixed
```
Default option. Discard the staging area but not working tree
``` git
git reset --soft
```
Keep both of the staging area and working tree
``` git
git reset --hard
```
Discard both staging area and working tree
``` git
git reflog
```
Check all the commit even if you are at a previous commit state
## Remotes
### Show Remotes
``` git
git remote
# with URL
git remote -v
# show details
git remote show <remote>
```
### Add Remote Repositories
``` git
git remote add <shortname> <url>
```
### Fetch
``` git
git fetch
git fetch <remote>
```
### Push
``` git
git push
git push <remote> <branch>
```
### Rename / Remove
``` git
git remote rename <remote> <new name>
git remote remove <remote>
```
## Branch
### Show branches
``` git
git branch # local
git branch --remotes # remote
git branch # both local and remote
```
### Create/Delete/Rename Branch
``` git
git branch <name> # create a branch
git branch -d <name> # delete a branch
git branch -m <old_name> <new_name> # rename a branch
```
### Move between Branches
``` git
git checkout <name> # move HEAD onto the branch
git checkout -b <name> # create a new branch and move HEAD onto it
```
### Upstream Branch
``` git
# Set upstream branch
git branch -u <remote>/<branch>
# Show upstream branches
git branch -vv
```
## Merge
Merge the branch to the current branch
``` git
git merge <branch_name>
```
Two cases may occur: **fastforward** and **non-fastforward**
### Non-Fastforward, fix conflict


We have to fix conflicts manually when non_fsatforward. Then commit the changes.

After that, we will see that we create a merge commit in git log
If we want to cancel the merging, type
``` git
git merge --abort
```
## Rebase
``` git
git rebase <branch_id>
```
### Non-Fastforward, fix conflict
Instead of committing the conflict-fixed changes, we just git add the change and type
``` git
git rebase --continue
````
Then :wq from the vim
And you will see that the commit in master(create conflict in master) is on top of the commit in branch

If we want to cancel the rebasing, type
``` git
git rebase --abort
```
## Iterative rebasing
Modify the commit tree
``` git
git rebase -i <commit_id>
```
Modify the commit tree from commit_id to the newest commit
Options:
``` git
p, pick <commit> = use commit
r, reword <commit> = edit the commit message
s. squash <commit> = use commit, but meld into previous commit
```

If we change

to

then the commit tree become

lsasdf
## SSH key
Generate ssh key (default path ~/.ssh/)
```
ssh-keygen
cat ~/.ssh/id_rsa.pub
```
## Work Flow Pattern
[Patterns for Managing Source Code Branches](https://martinfowler.com/articles/branching-patterns.html#maturity-branch)
## Reference
[Git Pro](https://git-scm.com/book)