# 我的 Git 指令小抄 ## 注意事項 * commit 只要提交的話,很難刪掉,還沒提交 commit,很容易不見 * git 不要 add 大檔案和機密檔案 * git config 可以設定 alias * 所有 HEAD, MASTER, origin ... 等關鍵字都只是一個指標 ## 名詞 * working directory: 工作目錄 * stagin area(index): 暫存區 * repo: 儲存庫 * remtoe, origin: remote 指的是遠端的 repo,概念,origin 是真的一個指標指向一個 url ``` $ git remote -v origin https://github.com/example/repo.git (fetch) origin https://github.com/example/repo.git (push) ``` * HEAD: 指向現在整個工作環境所在的 commit * MASTER(任意 branch-name): branch 指標,現在 branch 最新所在的位置,所以切換 branch 就是把 HEAD 指標移動到 MASTER 指標上 * `add`: 把 working directory 的檔案加入到 staged region * `commit`: 把 staged 的檔案加到 repo * `reset`: 移動 master(branch pointer) 跟 HEAD,危險 * `checkout`: 移動 HEAD [細說git reset和git checkout的不同之處](https://medicineyeh.wordpress.com/2015/01/22/%E7%B4%B0%E8%AA%AAgit-reset%E5%92%8Cgit-checkout%E7%9A%84%E4%B8%8D%E5%90%8C%E4%B9%8B%E8%99%95/) * `revert`: 製造一個 commit 來 revert 之前 commit 動的一些檔案 * `restore`: 復原檔案,不會動到指標,只動 working director [What is the `git restore` command and what is the difference between `git restore` and `git reset`?](https://stackoverflow.com/questions/58003030/what-is-the-git-restore-command-and-what-is-the-difference-between-git-restor) * `rebase`: 把一個 branch 以 ? commit 為基底,拔到另外一個以 ? commit 為基底的 branch 上。 ![image](https://hackmd.io/_uploads/SJN2r3KOp.png) 來自 [Git 中文教學](https://www.youtube.com/playlist?list=PLlyOkSAh6TwcvJQ1UtvkSwhZWCaM_S07d) 投影片截圖 ## Add and Commit 示意圖如下 ![image](https://hackmd.io/_uploads/rkLfWEIKa.png) - [image source](https://www.earthdatascience.org/workshops/intro-version-control-git/basic-git-commands/) ``` git add -p # 在已經 track 的檔案 git checkout -p # 跟 add -p 相反, 不熟悉且危險 git commit --amend # 融合跟修改上一次 commit ``` ## Restore ``` git restore <file> # work directory 的檔案修復到 HEAD (預設) git restore --staged <file> # 讓已經進 staged 的檔案回到 work directory git restore --source HEAD~2 <file> # 只修改一個檔案 # 以前沒有 git restore 都用 git checkout HEAD -- <filename>, 所以網路教學都教這個 ``` ## Reset ``` git reset [--soft | --mixed | --hard] [HEAD] # soft 只是退回版本 # hard 退回版本並且將所有 commit 刪掉,更改文件的動作也刪掉 # --mixed 重製暫存區, 與上一次 commit 一樣 ``` ## Log ``` git log —oneline load.cpp # 只跟 load.cpp 有關的 commit git log --name-only # 只顯示更改什麼檔案 ``` ## Diff ``` git diff # Working directory 跟 last commit 差異 git diff --staged # staged 跟 last commit 差異 git diff <commit> git diff <commit> <commit> git --no-pager diff # 不用往下慢慢拉 直接顯示全部 git diff -U1000 # 不要省略中間行數 最多 1000 行 git diff --color-words # 不會顯示 + - 符號,當你需要複製程式碼的時候很好用 ``` ## Checkout ``` git checkout <commit> # Move HEAD to the commit git checkout <branch> # Move HEAD to the branch git checkout -b <branch> # Create branch and checkout to that branch ``` ## Branch ``` git branch -m <new-branch-name> # 改名 git branch -a # List branch include remote git branch <nwe_branch> # Create branch git branch -d <branch> # 刪除 branch git branch -D <branch> # 無警告刪除 branch ``` ## Merge ``` git merge <branch> git merge <branch> --no-ff # merge 後會增加一個 commit 為 "merge ... branch" ``` ## Rebase and Modify commit * 不要 rebase 超過 branch base * rebase 前要先做備份 ``` git rebase <new base> # rebase current branch to new base, 自動調用共同的 commit git rebse --onto <new base> <ref commit> <branch> # 把 ref commit 到 branch 之間的 commits 拔到 new base 上面 git rebase -i # 以現在自己為目標 往前幾個做 rebase git rebase -i --root # 所有 commit rebase ``` ![image](https://hackmd.io/_uploads/HksWP3Y_p.png) ## Remote and Github ``` git remote -v # 查看 remote url git remote rename <a> <b> # 更改遠端 branch 名稱 git push <remote> <branch_1>:<branch_2> # 本地端 branch_1 遠端 branch_2 git push <remote> :<branch> # delete remote branch git branch --set-upstream-to <remote-branch> # 設定 upstream branch git branch --set-upstream-to=origin/develop develop Branch 'develop' set up to track remote branch 'develop' from 'origin'. git branch -vv # 查看現在 upstream 是誰 ``` ## Stash ``` git stash git stash list git stash pop stash@{n} git stahs drop stash@{n} ``` ## Patch and Cherry-Pick ... ## Reference [Git 中文教學](https://www.youtube.com/playlist?list=PLlyOkSAh6TwcvJQ1UtvkSwhZWCaM_S07d)