---
# System prepended metadata

title: Git
tags: [IT工具]

---

---
title: Git
---

## 關於版控
**1. 本地端版本控制:**
<img src="https://git-scm.com/book/en/v2/images/local.png" alt="VCS" width=416 height=356>

**2. 集中化版控:**
<img src="https://git-scm.com/book/en/v2/images/centralized.png" alt="CVCS" width=416 height=289>

**3. 分散式版控:**
<img src="https://git-scm.com/book/en/v2/images/distributed.png" alt="DVCS" width=402 height=487>

:::warning
1. 本地端版本控制:把檔案複製到另一資料夾標記時間
2. 集中化版控: 伺服器統一儲存，才能使不同電腦的人合作
3. 分散式版控: 解決伺服器壞掉檔案就會遺失的問題，因為每個用戶端都有repository的snapshot，可以完整還原
:::

## Git基礎觀念
- Git處理資料是 ++紀錄snapshots =timesO(1), 不是紀錄差異=O(n)++
- 大部分操作皆可在本地端完成，代表離線也可以工作
- Git用SHA-1檢查完整性
- Git通常只增加資料，使用者很難讓系統做出清除資料的動作
- Git三種狀態
  - modified
  - staged
  - committed
- Git三個工作區
  - Working directory
  - Staging area
  - Local repository(Git directory)一個project就有一個repository
- Git工作流程
  1. 我在Working directory修改檔案(檔案狀態=modified)
  2. 使用git add將檔案的snapshots預存到Staging area(檔案狀態=staged)
  3. 使用git commit預存區檔案的snapshots將永遠被存在Git directory

![git流程狀態圖](https://i.imgur.com/0Wtrh6N.jpg)


## Git初次設定
Git附帶一個git config工具，可以設定Git的外觀和行為，這些外觀和行為的參數被存在下列幾個檔案裡。
  - 檔案 **/etc/gitconfig**：裡面包含該系統所有使用者和使用者倉儲的預設設定。
    - 傳遞 --system 參數給 git config，它就會明確地從這個檔案讀取或寫入設定。
  - 檔案 **\~/.gitconfig、~/.config/git/config**：帳號專用的設定。
    - 傳遞 --global，就會明確地讓 Git 從這個檔案讀取或寫入設定
  - 任一Git directory裡的config檔案是 **.git/config**：此檔案為這個repository的專用設定。

:::danger
每個層級的設定皆覆蓋先前的設定，所以在 .git/config 的設定優先權高於在 /etc/gitconfig 裡的設定
:::

## Git 別名解釋
**- origin：** 遠端repository server的名稱
**- master：** 本地端創建時，默認branch名稱
**- origin/master：** origin表示遠端repositoty，指向master分支
**- origin/HEAD：** origin表示遠端repository，HEAD表示當前指向的branch



## Git help指令
```
$ git help <verb>
$ git <verb> --help
$ man git-<verb>
```
快速查詢，不須細節 `git add -h`


## 檢視
- not staged file
```
git status
git diff
```
- staged file
```
git diff --staged
equals to 
git diff --cached
```
:::info
git diff --staged會比對staged and last commit的詳細內容
:::

- 歷史日誌
```
git log //-p 可看每筆commit所做的修改
```
## 復原 
- staging area recommit
兩個情況：想add檔案到staging area | 更動提交訊息
```
git commit --amend //會將staging area再次拿來提交
```
:::danger
只能對local repo的提交，進行復原
:::

---
- modify to unmodify
```
git checkout -- <file>
```
---
- staged file move out from staging area
情況：想分別提交兩個檔案，不小心都add進staging area了
```
git reset HEAD <file> //--hard具風險
git restore --staged <file> //2.23.0以這為主
```
:::warning
試驗差別
:::

---
#### working diractory file復原成local repo file
```
git checkout -- <file>
```

## Remote repo

- Adding remote repo
```
git remote add <shortname> <url>
```

- Show remote repo
```
git remote -v
```

- Inspecting a remote
```
git remote show [remote-name]
```


## Fetch or Pull from remote
- Fetch or pull
```
git fetch <remote-name> //從remote repo下載到local repo
git pull <remote-name> //從remote repo下載到working dir
```

## Push to remote repo
```
git push [remote-hostname] [local-branch name]:[remote-branch-name]
```
:::info
若有人已經push過，我需先fetch對方的工作內容並整合，才能再次push
:::

## Rename or remove
- Rename
```
git remote rename [old-remote-name] [new-remote-name]
```
- Remove
```
git remote rm [remote-name]
```


```sequence
working dir->staging area: git add
```

## Git 基本指令
- git init：初始化一個新的Git存儲庫。
```git=
git init
```
- git clone：從遠端存儲庫克隆一份複製到本地。
```git=
git clone <repository_url>
```
- git add：將文件添加到暫存區。
```git=
git add <file>
```
- git commit：提交暫存區中的文件到本地存儲庫。
```git=
git commit -m "Commit message"
```
- git push：將本地提交推送到遠端存儲庫。
```git=
git push origin <branch_name>
```
- git pull：從遠端存儲庫拉取最新的更改到本地。
```git=
git pull origin <branch_name>
```
- git branch：列出本地分支。
```git=
git branch
```
- git checkout：切換到指定分支或恢復文件。
```git=
git checkout <branch_name>
```
- git merge：將指定分支合併到當前分支。
```git=
git merge <branch_name>
```
- git status：查看當前工作目錄的狀態。
```git=
git status
```

### 標籤意思
remote repo = origin，local repo不用有名稱 因為我都是在操作local repo

master origin/master: 我本地的master跟remote的master是同步的

#### Merge code
pull = fetch+merge ; pull只會拉一條branch


1. git checkout master. 切換到local master分支
2. git fetch origin/master，把remote的master拉進local repo
3. git merge mybranch，把我的分支合併到master
4. 解conflict
5. 發pr，叫別人拉我這條master到remote的master上


remote上每個人有自己的branch
pull自己的branch到working開發，push到remote repo自己的branch
等自己開發完成，拉pr，把origin master跟自己的branch合併

```bash=
aws codecommit list-repositories
```

```url=
https://git-codecommit.<region>.amazonaws.com/v1/repos/<repository-name>
```


# Fork 轉 Git Command
```=git
git status        -- 查看當前工作目錄的狀態
git fetch         -- 下載遠端更新，但先不合併到你的程式碼
git pull          -- 下載遠端更新並自動嘗試合併 (Fetch + Merge)
git checkout -b <new_branch_name>    -- 建立並切換到新分支
```