---
# System prepended metadata

title: Git 懶人包
tags: [Templates, Documentation]

---

---
title: 'Project documentation template'
disqus: hackmd
---

Git 懶人包
===


## 目錄

[TOC]

## 克隆專案

### 第一次抓遠端專案時(抓主分支)

1. 在 local cd 到想存專案的地方 (ex.桌面)
2. 下指令
```code=
git clone git@gitlab.com:xxx/xxx-dashboard.git
```
### 第一次抓遠端指定分支的檔案時
要加上 -b beta 參數
```code=
git clone -b beta git@gitlab.com:xxx/xxx-dashboard.git
```


### 第一次要開始做自己的新功能時：
1. 先做 更新主線 的section
2. 根據主線新增分支（概念上就是複製主線）
（假設分支名是 main, origin/main 就是遠端的main分支）

```code=
// 新增一個分支並以 origin/main 為上游分支
git checkout -b dev/1.0.0 origin/main
```
3. 用 git branch 確認自己在自己的分支上就可以安心做事了
> 之後只要直接 git checkout dev/1.0.0 就表示在自己的分支上做事了



### 自己的功能做好要更新到“自己的上游分支”
1. 東西存到暫存區
```code=
git add .
```

2. 確認並為這次儲存下註解 (ex. 完成圖像處理功能)
```code=
git commit -m "完成圖像處理功能"
```

3. 更新到自己的遠端
```code=
git push
```


### 更新分支

1. 在自己電腦 cd 到專案資料夾（ex. Desktop/UniProject）
2. 先切到 beta 分支（也就是保證正確的分支）
```code=
// 看一下自己在哪個分支
git branch

// 切到 beta 分支
git checkout beta
```

3. 拉回檔案
```shell=
// 從分支或主線拉檔案回來
git pull
```

### 常見問題：我的git遠端 beta 分支稍早已經有更新，我要如何正確合併到我電腦上的版本，並且不會讓我變更的資料被覆蓋？
1. 確保目前工作目錄是乾淨的: 在合併之前，最好先確保你的工作目錄是乾淨的，沒有任何未提交的變更。你可以使用 `git status` 來檢查。
2. 切換到你想要合併的分支: 如果你現在不在 beta 分支，你可以使用 git checkout beta 來切換。
3. 取得遠端的更新: 使用 git fetch 取得遠端的更新。這個命令會下載遠端的變更，但不會自動合併或修改你目前的工作目錄。
```code=
git fetch origin
```
4. 查看變更: 在合併之前，你可能想先查看遠端和本地分支之間的差異。這可以幫助你了解即將合併的變更。使用以下命令查看差異：
```code=
git diff beta..origin/beta
```
5. 合併變更: 使用 git merge 來合併遠端的 beta 分支到你的本地分支。因為你想要保留你的變更，所以使用 --no-ff 選項，這樣即使合併是快進的（fast-forward），也會產生一個新的合併提交。
```code=
git merge origin/beta --no-ff
```


## 推專案
### 將電腦上的資料夾推送到空的 Gitlab 專案分支
```code=
cd 資料夾
git init --initial-branch=main
git remote add origin git@gitlab.com:xxx/xxx-dashboard.git
git add .
git commit -m "Initial commit"
git push --set-upstream origin main
```


---

## 移除 commit
```code=
// 移除最後第 n 個 commits
git reset --hard HEAD~n
```
---
## 新增分支
```code=
// Create and checkout new local branch
git checkout -b <branch>

// Push to remote
// --set-upstream 可以簡寫為 -u
git push -u origin <branch>
```

---
## 砍分支
```code=
// 刪除自己電腦上的分支(必須先離開該分支)
git branch -d <分支名稱>

// 移除遠端的分支 (如果你知道你在幹嘛！)
git push <remote_name> --delete <分支名稱>
```
---

## 重新命名
```code=
git mv <old_file_name> <new_name>
```
---
## 設定分支追踪關係

這兩行指令讓你先切換到 dev/1.0.0 分支，
然後將 origin/main 設定為 dev/1.0.0 的上游分支。
這種設定在多人協作、多分支開發的情境中非常有用
特別是當某個特定分支需要追踪另一個遠端分支的更新時。
```code=
git checkout dev/1.0.0

git branch -u origin/main
```
> *origin/main = 遠端 main 分支
> main = 電腦上的 main 分支*

---
## 排除某些文件被 git add . 加入追蹤
如果你想排除某些文件或目錄不被 Git 追蹤，可以使用 `.gitignore` 文件。`.gitignore` 文件允許你指定不應該被 Git 追蹤的文件或目錄模式。

以下是如何使用 `.gitignore` 來排除文件：
[教學影片](https://youtu.be/AbKPZv_TwDo?si=Ga5Lz5R0v1VWB_i4)
[![教學影片](https://img.youtube.com/vi/AbKPZv_TwDo/hqdefault.jpg)](https://youtu.be/AbKPZv_TwDo?si=Ga5Lz5R0v1VWB_i4)

1. 在你的 Git 儲存庫根目錄下，建立或編輯 .gitignore 文件。
2. 在 `.gitignore` 文件中，添加你希望 Git 忽略的文件或目錄。例如：


```code=
# 依賴和編譯產物
vendor/                # 通常用於 PHP 依賴，如由 Composer 安裝的
node_modules/          # 如果你使用了 Node.js 工具或框架，如 webpack 或 Babel

# 操作系統生成的文件
.DS_Store              # macOS
Thumbs.db              # Windows
.Trash-*               # Linux

# IDE 和編輯器配置和緩存
.vscode/
.idea/
*.suo
*.user
*.sln.docstates
*.sublime-*            # Sublime Text 可能會生成的暫存或工作空間文件
*.swp                 # Vim 編輯器的暫存文件
*.swo                 # Vim 編輯器的暫存文件

# 日誌和暫存文件
*.log
*.tmp
*.temp

# 其他
.env                   # 環境變量文件
.git/

# 一些 PHP 工具或框架可能生成的文件/目錄
php_errors.log

# 如果你有使用資料庫，可能還需要考慮
*.sql
*.sqlite

# 如果你有使用圖形編輯工具
*.psd                  # Photoshop 文件
*.ai                   # Adobe Illustrator 文件
*.sketch               # Sketch 文件

# 如果你有 CSS/SASS 的編譯產物
/css/dist/
/sass/cache/
```
---
## 有些文件已被追蹤了，怎麼把它剔除？
如果某些文件已被 Git 追蹤，但你現在想將它們從 Git 的追蹤中移除（但保留在你的工作目錄中），你可以使用以下的步驟：
1. 更新 `.gitignore` 文件：首先，確保你的 `.gitignore` 文件中包含了你不想追蹤的文件或目錄模式。
2. 使用 `git rm --cached`：這個命令將文件從 Git 索引中移除，但保留在你的工作目錄中。

例如，
```code=
// 要停止追蹤 myfile.txt，你可以執行：
git rm --cached myfile.txt

// 如果你想一次移除多個文件或目錄，你可以列舉它們：
git rm --cached file1.txt file2.txt dir/file3.txt

// 如果你想移除整個目錄，使用 -r 選項：
git rm --cached -r mydir/

```
3. 提交更改：最後，你需要提交這些更改以將其記錄到 Git 歷史中：
```code=
git commit -m "Remove some tracked files"
```
5. 推送到遠端儲存庫（如果需要的話）：
```code=
git push
```

### 小技巧
> 我想排除掉已被追蹤的所有 `.DS_Store`
包含所有子目錄下的 `.DS_Store`


1. 先移除被追蹤的 .DS_Store
```code=
git rm --cached -r .DS_Store
```

2. 從 Git 中移除所有 .DS_Store 文件
```code=
git ls-files -z | grep -z -i '\.DS_Store$' | xargs -0 git rm --cached
```
*這個命令組合首先使用 git ls-files 來找到所有已被追蹤的 .DS_Store 文件，然後使用 git rm --cached 將它們從 Git 索引中移除。*

3. 更新 `.gitignore` 文件：在 `.gitignore` 文件中添加以下内容，以確保未來不會再次追蹤 `.DS_Store` 文件：
```code=
// gitignore 加上這行
.DS_Store
```

4. 提交更改
```code=
git commit -m "移除所有被追蹤的 .DS_Store 文件"
```

5. 推送到遠端儲存庫（如果需要的話）：
```code=
git push
```


---
## 如果想要將文件退回之前的版本呢？
如果你想將文件退回到之前的版本，你可以使用 Git 的多種方式來達到這個目的。以下是幾種常見的方法：

```code=
// 先查看有哪些 <commit_hash>
git log
```
### 1. 使用 `git checkout`
這允許你將特定文件退回到某個特定的提交：
```code=
// 將文件退回到某個特定的提交
git checkout <commit_hash> -- path/to/file.ext
```
其中 <commit_hash> 是你想退回到的提交的哈希值（或其前幾個字符）。

例如，如果你想退回到 f7d3a6 這個提交的 index.php 文件版本，你可以使用：
```code=
git checkout f7d3a6 -- index.php
```


### 2. 使用 `git revert`
如果你想將一個（或多個）提交進行反轉，可以使用 git revert。這將創建一個新的提交，該提交的效果是撤銷之前的更改。
```code=
// 將文件退回到某個特定的提交
git revert <commit_hash>
```

### 3. 使用 `git reset`
如果你想將整個工作目錄和索引退回到之前的提交，你可以使用 git reset：

#### 使用 --soft 會保留工作目錄和索引中的更改：
```code=
// 將文件退回到某個特定的提交
git reset <commit_hash> -- path/to/file.ext
```

#### 使用 --mixed（這是預設的）只會保留工作目錄中的更改：
```code=
git reset --mixed <commit_hash>
```