# Git

## Merge & Rebase

### Merge

<figure><img src="https://1374779285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MFW3x2aqEO8GF2kr3VU%2Fuploads%2FbmsSvfoaXv8bd6qvDDIV%2Fimage.png?alt=media&#x26;token=fa74efa3-0aac-41b9-9ddc-5ab3add937c9" alt=""><figcaption></figcaption></figure>

* Merging is nice because it’s a _non-destructive_ operation. The existing branches are not changed in any way.

### Rebase

<figure><img src="https://1374779285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MFW3x2aqEO8GF2kr3VU%2Fuploads%2FUsHHq7hr5bEMGLyIYw0r%2Fimage.png?alt=media&#x26;token=dcf91fa5-95a6-42ca-b609-989a45a2ce9b" alt=""><figcaption></figcaption></figure>

* Rebase  moves all of the commits in feature on top of main, it changes the commit history of feature to make the history more clean
* Make sure the feature is only for your use, since branch’s history has diverged from everybody else’s.
* After rebased , `force push` is needed in order to rewrite the history

## Sub Module

### Create SubModule

```bash
 git submodule add (--force) -b <branch> <git url>
```

### Update SubModule

```bash
cd directory
git pull
```

### Existing SubModule Initialization

```bash
git submodule init
git submodule update
```

### Delete SubModule

```bash
git rm <directory>
```



## Fork

* Firstly,  it can make a copy of project to your repo through forking

<figure><img src="https://1374779285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MFW3x2aqEO8GF2kr3VU%2Fuploads%2Fer7JzQPC0rUSDCZDD8C4%2Fimage.png?alt=media&#x26;token=2f145246-0873-4042-9640-223bb2166573" alt=""><figcaption></figcaption></figure>

* Then, clone the code on local
* After that,  execute the following commands to update the code from source if needed

```bash
# Add the remote, call it "upstream":

git remote add upstream https://github.com/whoever/whatever.git

# Fetch all the branches of that remote into remote-tracking branches

git fetch upstream

# Make sure that you're on your main branch:

git checkout main

# Rewrite your main branch so that any commits of yours that
# aren't already in upstream/main are replayed on top of that
# other branch:

git rebase upstream/main
```

<figure><img src="https://1374779285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MFW3x2aqEO8GF2kr3VU%2Fuploads%2F5jwGwxl9i1lawTYEPBz6%2Fimage.png?alt=media&#x26;token=c4409f8a-f01f-4748-a61c-85f96dba2d79" alt=""><figcaption></figcaption></figure>

## Reset

* To cancel the committed change and reset the head

### Hard&#x20;

* Discard all the committed changes and staged/ unstaged  changes

### Mixed

* Put back your committed changes and staged changes into unstaged changes&#x20;

### Soft

* Only put back your commited changes into unstaged changes

## Tracing

### Diff

* To compare the change of file&#x20;

<figure><img src="https://1374779285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MFW3x2aqEO8GF2kr3VU%2Fuploads%2FWHUI8gyXCuShPdJkGMVZ%2Fimage.png?alt=media&#x26;token=aa053dff-0b40-4957-868a-021dca2d8601" alt=""><figcaption></figcaption></figure>

```bash
git diff <your file>
```

### Log

* To get the commit history of file

<figure><img src="https://1374779285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MFW3x2aqEO8GF2kr3VU%2Fuploads%2FMaWvoHsjfKqBcHD0CRxq%2Fimage.png?alt=media&#x26;token=547cfc74-5182-4db4-96a2-2ae57434a0f2" alt=""><figcaption></figcaption></figure>

```bash
git log <your file>
```



### Blame

* To get file change and each commit line by line

<figure><img src="https://1374779285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MFW3x2aqEO8GF2kr3VU%2Fuploads%2F3Sahi27PtsXzBycb9TSl%2Fimage.png?alt=media&#x26;token=9b9d018f-2674-4ce7-aa2f-9fc5fb50c208" alt=""><figcaption></figcaption></figure>

```bash
git blame <your file>
```

### Grep

* To search the file based on keyword

<figure><img src="https://1374779285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MFW3x2aqEO8GF2kr3VU%2Fuploads%2FIlvgRV7ed8UsbOrrdccm%2Fimage.png?alt=media&#x26;token=8dd0196b-c701-40de-8267-4eaade00f14f" alt=""><figcaption></figcaption></figure>

```bash
git grep <keyword>
```



## Reflog

* To record all your operations on local, including changing branch

```bash
git reflog <branch>
```

<figure><img src="https://1374779285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MFW3x2aqEO8GF2kr3VU%2Fuploads%2FWKhfVNavoeKQnNq83iL1%2Fimage.png?alt=media&#x26;token=af8b95a0-28fe-41c4-a369-b0def68b6b59" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1374779285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MFW3x2aqEO8GF2kr3VU%2Fuploads%2Fc5Ghu1JSIsvKJBJ1NXE3%2Fimage.png?alt=media&#x26;token=4baed433-1292-43f7-b3c5-0bf746bd859d" alt=""><figcaption></figcaption></figure>

* If you want to recover some of operated changes, such as reset change, deleted branch change
* You can checkout based on the history

```bash
git checkout <historyNum>
```



## Revert & Cherry pick

* Cherry pick and revert  can both select the commit of content from other branch into current branch
* But revert is to select the opposite version of the commit

## Git Hook

<figure><img src="https://1374779285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MFW3x2aqEO8GF2kr3VU%2Fuploads%2FUwoPVQSwoNNF9vbydlMc%2Fimage.png?alt=media&#x26;token=ec4ed337-2f27-454f-aee6-7d9fc448c9ba" alt=""><figcaption></figcaption></figure>

* Hooks can reside in either local or server-side repositories, and they are only executed in response to actions in that repository. Here is the list of action:
* `pre-commit`
* `prepare-commit-msg`
* `commit-msg`
* `post-commit`
* `post-checkout`
* `pre-rebase`

## References

{% embed url="https://www.atlassian.com/git/tutorials/git-hooks" %}

{% embed url="https://github.com/doggy8088/Learn-Git-in-30-days/blob/master/zh-tw/01.md" %}

{% embed url="https://git-scm.com/docs/" %}
