###### tags: `Plus` `Git` `GitHub`
# Git指令筆記
## Git設定指令:
>| 命令 | 說明 | |
>| --- | --- | --- |
>| git config user.name "Git1"| 設定個別識別資料簽名為 `` Git1 `` | |
>| git config user.email "git@g.com"| 設定個別識別資料E-Mail為 `` git@g.com `` | |
>| git config --global user.name "Git1"| 設定預設識別資料簽名為 `` Git1 `` | |
>| git config --global user.email "git@g.com"| 設定預設識別資料E-Mail為 `` git@g.com `` | |
>
## Git工作目錄:
>| 命令 | 說明 | |
>| --- | --- | --- |
>| git init | 初始化當前工作目錄(為該目錄設置Git) | |
>| git add . | 將工作目內所有檔案置入暫存區(stage) | |
>| git add "filename" | 將 `` filename `` 置入暫存區(stage) | |
>| git rm --cached "filename" | 將 `` filename `` 從暫存區(stage)中移除 | |
>| git commit -a | 已變更的檔案提交至本地庫(local repoistry) | |
>| git commit -m "測試編輯評論" "filename" | 將 `` filename `` 提交至本地庫(local repoistry),並註記 `測試編輯評論` | |
>| git status | 檢查本地庫(local repoistry)與暫存區(stage)的狀態|
## Git查詢指令:
>| 命令 | 說明 | |
>| --- | --- | --- |
>| git log | 顯示Git版本紀錄 | `q`|
>| git log --pretty=oneline | 顯示Git版本紀錄(簡化顯示:無上傳者、時間) | |
>| git log --oneline | 顯示Git版本紀錄(簡化顯示:sh1) | |
>| git reflog | 顯示Git版控操作紀錄 | |
>| git diff | 比較目前檔案與最新版的差異 | |
>| git diff HEAD^ "filename" | 比較檔案 `filename` 與上一版的差異 | |
## Git版控指令:
>| 命令 | 說明 | |
>| --- | --- | --- |
>| git reset --hard "sh1" | Git還原至 `sh1` 版本 | |
>| git reset --hard HEAD^ | Git還原至前一版本 | |
>| git reset --hard HEAD^^^ | Git還原至前三版本 | |
>| git reset --hard HEAD~3 | Git還原至前三版本 | |
>| git checkout . | Git還原至沒有commit前的版本 | |
>| git checkout "sh1" "filename" | 將檔案 `filename` 還原至指定版本 | |
## Git分支指令:
>| 命令 | 說明 | |
>| --- | --- | --- |
>| git branch -v | 查詢本地庫的分支 |
>| git branch -a | 查詢本地庫與遠端庫的分支 |
>| git branch "vername" | 創建新分支並命名為 `vername` |
>| git branch -d "vername" | 刪除分支名稱 `vername` |
>| git branch -D "vername" | 創建新分支並命名為 `vername` |
>| git branch -m "vername" "newname" | 將分支 `vername` 更名為 `newname` |
>| git checkout "vername" | 切換分支名稱 `vername` |
>| git checkout -b "vername" | 新增並切換分支名稱 `vername` |
>| git merge "vername" | 將目前版本與分支 `vername` 合併 |
>| git rebase "vername" | 以 `vername` 為基底衍合當前分支 |
>| git checkout --ours "filename" | 切換檔案 `filename` 使用切換前版本分支 |
>| git checkout --theirs "filename" | 切換檔案 `filename` 使用切換後版本分支 |
## Git遠端指令:
> | 命令˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰| 說明 ||
> | --- | --- | --- |
> | git clone "URL"| 將該遠端儲存庫 `URL` 下載到當前工作目錄 | |
> | git remote| 顯示所有遠端儲存庫版本 | |
> | git remote -v| 顯示所有遠端儲存庫版本與URL | |
> | git remote add "remote_name" "URL" | 將該遠端儲存庫 `URL` 命名為 `remote_name` | |
> | git remote rename "remote_name" "newname" | 將該遠端儲存庫名稱 `remote_name` 更名為 `newname` | |
> | git remote rm "remote_name" | 移除遠端儲存庫名稱 `remote_name` 與該URL |
> | git push | 將現在分支上傳至遠端儲存庫 | |
> | git push -f | 將現在分支強制上傳並覆蓋至遠端儲存庫(慎用) | |
> | git push "remote_name" "vername" | 將分支名稱 `vername` 上傳至遠端儲存庫 `remote_name` | |
> | git pull "remote_name" "vername" | 將遠端儲存庫 `remote_name` 合併至分支名稱 `vername` | |
> | git fetch | 擷取所有遠端儲存庫 |
> | git fetch <branch_name> | 擷取遠端儲存庫的 `varname` 分支 |
## Git標籤指令:
> | 命令˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰˰| 說明 ||
> | --- | --- | --- |
> | git tag "輕量標籤"| 為目前的版本添加 `輕量標籤` 作為標籤 | |
> | git tag -am "標籤名稱" "註解xxx"| 為目前的版本添加 `標籤名稱` 並以 `註解xxx` 作為註解 | |
> | git tag -d "輕量標籤"| 為目前的版本刪除名稱為 `輕量標籤` 的標籤 | |
---
## Git 常用指令:
```bash
git log --oneline --graph
# log 精簡化紀錄
git log -S "ss"
# log 搜尋commit的檔案內容中包含"ss"的紀錄
git log -p "filename"
# log 搜尋filename檔案commit紀錄
git blame "filename"
# log 搜尋filename檔案commit紀錄(單行)
git log --author="aa"
# log 搜尋作者為"aa"的commit紀錄
git log --grep="cc"
# log 搜尋commit文字中包含"cc"的紀錄
git log --after="2001-02-03 04:56" --before="2099-09-09 23:23"
# log 搜尋此時區間的commit紀錄(參數至少包含年月日)
git commit --amend -m "xxxx"
#重新修改本次commit備註
```
## 將某檔案從Git紀錄中完全移除:
```bash
git filter-branch -f --tree-filter "rm -f XXXX/XXXX.ext"
# filter-branch 指令把檔案XXXX/XXXX.ext從工作目錄裡移掉
rm .git/refs/original/refs/heads/master
# 刪除Git管理目錄中的 filter-branch 備份點
git reflog expire --all --expire=now
# Reflog 立刻過期(不然預設要等 30 天)
git gc --prune=now
# 啟動 Git 的資源回收機制,請垃圾車來立刻把它們載走
git fsck
# 檢查
```
## 隱藏部份檔案,不上傳至遠端庫Repository:
git所管理資料夾內創建 ==.gitignore== 隱藏檔案,在編輯內容:
```bash
# 檔案名稱 .gitignore
# 忽略 secret.yml 檔案
secret.yml
# 忽略 config 目錄下的 database.yml 檔案
config/database.yml
# 忽略所有 db 目錄下附檔名是 .sqlite3 的檔案
/db/*.sqlite3
# 忽略所有附檔名是 .tmp 的檔案
*.tmp
# 當然你要忽略自己也可以,只是通常不會這麼做
# .gitignore
```
## 上傳至遠端儲存庫失敗(error: failed to push some refs to):
上傳至遠端儲存庫失敗訊息: `error: failed to push some refs to`
最常見的原因為遠端庫資料與本地庫資料有所差異,必須先將遠端庫更新到本地庫中(pull),`git pull` 指令會更新本地庫資料至最新,過程會自動判斷是否有衝突(conflict),若有須另外藉由 `git merge` 解決問題,若本地庫更新完成後,即可再次 `git push`。
以下是未有衝突發生的成功案例:
> ```sass
> d:\Personal File\Desktop\GOLang\GitStudy (master -> origin)
> λ git commit -a -m "測試衝突"
> [master f8c17be] 測試衝突
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> d:\Personal File\Desktop\GOLang\GitStudy (master -> origin)
> λ git push "初始版" "master"
> To https://github.com/DukeHuang/GitStudy.git
> ! [rejected] master -> master (fetch first)
> error: failed to push some refs to 'https://github.com/DukeHuang/GitStudy.git'
> hint: Updates were rejected because the remote contains work that you do
> hint: not have locally. This is usually caused by another repository pushing
> hint: to the same ref. You may want to first integrate the remote changes
> hint: (e.g., 'git pull ...') before pushing again.
> hint: See the 'Note about fast-forwards' in 'git push --help' for details.
>
> d:\Personal File\Desktop\GOLang\GitStudy (master -> origin)
> λ git pull "初始版" "master"
> remote: Enumerating objects: 5, done.
> remote: Counting objects: 100% (5/5), done.
> remote: Compressing objects: 100% (2/2), done.
> remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
> Unpacking objects: 100% (3/3), done.
> From https://github.com/DukeHuang/GitStudy
> * branch master -> FETCH_HEAD
> ccdd6b7..87f9ee8 master -> 初始版/master
> Merge made by the 'recursive' strategy.
> A.txt | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> nothing to commit, working tree clean
>
> d:\Personal File\Desktop\GOLang\GitStudy (master -> origin)
> λ git push "初始版" "master"
> Enumerating objects: 9, done.
> Counting objects: 100% (8/8), done.
> Delta compression using up to 4 threads
> Compressing objects: 100% (4/4), done.
> Writing objects: 100% (5/5), 664 bytes | 664.00 KiB/s, done.
> Total 5 (delta 0), reused 0 (delta 0)
> To https://github.com/DukeHuang/GitStudy.git
> 87f9ee8..ea840d5 master -> master
>
> ```
以下是衝突發生並利用 `git checkout --ours` 解決案例:
> ```sass
> d:\Personal File\Desktop\GOLang\GitStudy (master -> origin)
> λ git commit -a -m "合併衝突"
> [master da68b1b] 合併衝突
> 2 files changed, 3 insertions(+), 3 deletions(-)
>
> d:\Personal File\Desktop\GOLang\GitStudy (master -> origin)
> λ git push "初始版" "master"
> To https://github.com/DukeHuang/GitStudy.git
> ! [rejected] master -> master (fetch first)
> error: failed to push some refs to 'https://github.com/DukeHuang/GitStudy.git'
> hint: Updates were rejected because the remote contains work that you do
> hint: not have locally. This is usually caused by another repository pushing
> hint: to the same ref. You may want to first integrate the remote changes
> hint: (e.g., 'git pull ...') before pushing again.
> hint: See the 'Note about fast-forwards' in 'git push --help' for details.
>
> d:\Personal File\Desktop\GOLang\GitStudy (master -> origin)
> λ git pull "初始版" "master"
> remote: Enumerating objects: 5, done.
> remote: Counting objects: 100% (5/5), done.
> remote: Compressing objects: 100% (2/2), done.
> remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
> Unpacking objects: 100% (3/3), done.
> From https://github.com/DukeHuang/GitStudy
> * branch master -> FETCH_HEAD
> ea840d5..27c107b master -> 初始版/master
> Auto-merging A.txt
> CONFLICT (content): Merge conflict in A.txt
> Automatic merge failed; fix conflicts and then commit the result.
>
> d:\Personal File\Desktop\GOLang\GitStudy (master -> origin)
> λ git checkout --ours "A.txt"
> Updated 1 path from the index
>
> d:\Personal File\Desktop\GOLang\GitStudy (master -> origin)
> λ git commit -a -m "解決衝突"
> [master a5b653b] 解決衝突
>
> d:\Personal File\Desktop\GOLang\GitStudy (master -> origin)
> λ git push "初始版" "master"
> Enumerating objects: 11, done.
> Counting objects: 100% (10/10), done.
> Delta compression using up to 4 threads
> Compressing objects: 100% (3/3), done.
> Writing objects: 100% (5/5), 489 bytes | 489.00 KiB/s, done.
> Total 5 (delta 1), reused 0 (delta 0)
> remote: Resolving deltas: 100% (1/1), done.
> To https://github.com/DukeHuang/GitStudy.git
> 27c107b..a5b653b master -> master
> ```
## 解決合併衝突(merge & conflict):
將遠端庫更新到本地庫中(pull),`git pull` 指令會更新本地庫資料,合併時易容易發生衝突(conflict),若使用手動處理衝突可利用編輯器的比較工具分析,修改完成後再使用 `git add` 指令將檔案新增至暫存庫,再 `git commit` 成為一個新版本。
以下是手動處理合併衝突(conflict)的過程:
> ```sass
> d:\Personal File\Desktop\GOLang\GitStudy (master -> origin)
> λ git pull "初始版" "master"
> remote: Enumerating objects: 9, done.
> remote: Counting objects: 100% (9/9), done.
> remote: Compressing objects: 100% (4/4), done.
> remote: Total 6 (delta 0), reused 0 (delta 0), pack-reused 0
> Unpacking objects: 100% (6/6), done.
> From https://github.com/DukeHuang/GitStudy
> * branch master -> FETCH_HEAD
> b837896..7a868fc master -> 初始版/master
> Auto-merging B.txt
> CONFLICT (content): Merge conflict in B.txt
> Auto-merging A.txt
> CONFLICT (content): Merge conflict in A.txt
> Automatic merge failed; fix conflicts and then commit the result.
>
> d:\Personal File\Desktop\GOLang\GitStudy (master -> origin)
> λ git status
> On branch master
> Your branch is ahead of 'origin/master' by 11 commits.
> (use "git push" to publish your local commits)
>
> You have unmerged paths.
> (fix conflicts and run "git commit")
> (use "git merge --abort" to abort the merge)
>
> Unmerged paths:
> (use "git add <file>..." to mark resolution)
>
> both modified: A.txt
> both modified: B.txt
>
> no changes added to commit (use "git add" and/or "git commit -a")
>
> d:\Personal File\Desktop\GOLang\GitStudy (master -> origin)
> λ git add .
>
> d:\Personal File\Desktop\GOLang\GitStudy (master -> origin)
> λ git commit -a -m "解決合併衝突"
> [master 08d01de] 解決合併衝突
>
> d:\Personal File\Desktop\GOLang\GitStudy (master -> origin)
> λ git push "初始版" "master"
> Enumerating objects: 13, done.
> Counting objects: 100% (13/13), done.
> Delta compression using up to 4 threads
> Compressing objects: 100% (4/4), done.
> Writing objects: 100% (7/7), 721 bytes | 721.00 KiB/s, done.
> Total 7 (delta 0), reused 0 (delta 0)
> To https://github.com/DukeHuang/GitStudy.git
> 7a868fc..08d01de master -> master
>
> ```
若想還原pull所造成的衝突,可利用 `git reset --hard HEAD@{0}` 指令還原操作:
> ```sass
> d:\Personal File\Desktop\GOLang\GitStudy (master -> origin)
> λ git pull "初始版" "master"
> remote: Enumerating objects: 9, done.
> remote: Counting objects: 100% (9/9), done.
> remote: Compressing objects: 100% (4/4), done.
> remote: Total 6 (delta 0), reused 0 (delta 0), pack-reused 0
> Unpacking objects: 100% (6/6), done.
> From https://github.com/DukeHuang/GitStudy
> * branch master -> FETCH_HEAD
> b837896..7a868fc master -> 初始版/master
> Auto-merging B.txt
> CONFLICT (content): Merge conflict in B.txt
> Auto-merging A.txt
> CONFLICT (content): Merge conflict in A.txt
> Automatic merge failed; fix conflicts and then commit the result.
>
> d:\Personal File\Desktop\GOLang\GitStudy (master -> origin)
> λ git status
> On branch master
> Your branch is ahead of 'origin/master' by 11 commits.
> (use "git push" to publish your local commits)
>
> You have unmerged paths.
> (fix conflicts and run "git commit")
> (use "git merge --abort" to abort the merge)
>
> Unmerged paths:
> (use "git add <file>..." to mark resolution)
>
> both modified: A.txt
> both modified: B.txt
>
> no changes added to commit (use "git add" and/or "git commit -a")
>
> d:\Personal File\Desktop\GOLang\GitStudy (XTest -> origin)
> λ git reflog
> d70266d (HEAD -> XTest) HEAD@{0}: commit: Xtest Ver
> b837896 HEAD@{1}: checkout: moving from master to XTest
> 08d01de (初始版/master, master) HEAD@{2}: commit (merge): 解決合併衝突
> d7dfe6c HEAD@{3}: commit: X修改版
> b837896 HEAD@{4}: commit: 合併版本
> a5b653b HEAD@{5}: commit (merge): 解決衝突
> da68b1b HEAD@{6}: commit: 合併衝突2
> ea840d5 HEAD@{7}: pull 初始版 master: Merge made by the 'recursive' strategy.
> f8c17be HEAD@{8}: commit: 測試衝突
> ccdd6b7 HEAD@{9}: commit: 修改初始注解
> 948d58b HEAD@{10}: commit: 修改初始注解
> e183b37 HEAD@{11}: commit: 初始版
> 0c14f3d (origin/master, origin/HEAD) HEAD@{12}: clone: from https://github.com/DukeHuang/GitStudy.git
>
> d:\Personal File\Desktop\GOLang\GitStudy (XTest -> origin)
> λ git reset --hard HEAD@{0}
> HEAD is now at d70266d Xtest Ver
> ```
## Gitlab 搬遷:
Gitlab方式先將舊專案 git 鏡像clone,在另外push。
> ```sass
> git clone --mirror https://git.xxx1/old-poject.git
> git remote rename origin old-poject
> git remote add origin https://oauth2:PersonalAccessToken@xxx2/new-poject.git/
> git push -u origin --all
> git push -u origin --tags
> ```