# Learn Git ###### tags: git ## Learn Git 有git tree,真的超級棒! https://learngitbranching.js.org/ ![](https://i.imgur.com/CFw2vYw.png) `undo` 回到上一步 ### 1: 介紹 git commit * commit * branch 開分枝 * checkout * cherry-pick * reset 返回前一版 * revert '修改版本 * rebase 更新到最新 * merge 合併 [解答](http://blog.codepiano.com/2013/12/22/learn-git-branching-solution-main) 1.1 git commit 1.2 git branch [branch name] 建立分支 git checkout [branch name] 切換過去 ``` git branch bugFix git checkout bugFix ``` 可以精簡為: `git checkout -b bugFix` #### 1.3 git merge ![](https://i.imgur.com/U32nenQ.png) * 建立新的 branch,叫做 bugFix * 用 git checkout bugFix 切換到 bugFix branch * commit 一次 * 用 git checkout 切換回 master branch * 再 commit 一次 * 用 git merge 將 bugFix merge 到 master ``` git branch bugFix git checkout bugFix git commit ``` C1裡有master和新建的bugFix,checkout是移動過去,可以精簡為: ``` git checkout -b bugFix git commit ``` 切換回master後在master commit,再把bugFix merge到master: ``` git checkout master git commit git merge bugFix ``` 切換到想合併分支的位置 merge參數是想合併過來的分支 #### 1.4 git rebase ![](https://i.imgur.com/9E5XDSF.png) rebasing 是 merge branch 的第二種方法。rebasing 就是取出一連串的 commit,"複製"它們,然後把它們接在別的地方。 雖然聽起來難以理解,rebasing 的優點是可以建立更線性的 commit history。假如只允許使用 rebasing 的話,則我們的 repo 中的 commit log 或者是 commit history 會更加簡潔好看。 * 建立 bugFix branch * commit 一次 * 切換回 master branch 再 commit 一次 * 再次切換到 bugFix branch,接著 rebase bugFix 這個 branch 到 master branch 上 ``` git checkout -b bugFix git commit git checkout master git commit git checkout bugFix git rebase master ``` git checkout bugFix 切換到要複製的分支 git rebase master 參數放要複製過去的分支 ### 2. Head #### 2.1 分離HEAD `git checkout C4` 或者滑鼠點一下C4 #### 2.2 相對引用 `git checkout C4^` Head就是現在的位置 (在上一關會用*提示) ^是相對位置往上(上一個commit)移動一層 * 使用 ^ 向上移動一個 commit #### 2.3 相對引用 * 使用 ~<num> 向上移動多個 commit Branch forcing `git branch -f master HEAD~3` (強制)移動 master 指向從 HEAD 往上數的第三個 parent commit。 ![](https://i.imgur.com/W5G7vpo.png) ![](https://i.imgur.com/CFmjesh.png) `git branch -f master C6` 雖然Head在C2,但強制移動到C6位置建立分支master `git branch -f bugFix C0` 同理 `git checkout C1` 也可以 `git checkout HEAD^` `git checkout HEAD~1` `git checkout C2^` `git checkout C2~1` #### 2.4 取消 git 的修改 ![](https://i.imgur.com/4EjK0Ec.png) git reset HEAD~1 用在修改local branch ![](https://i.imgur.com/CZLkYOK.png) git revert HEAD 用在修改remote branch `git reset C3^` 注意一下*在哪裡~ ``` git checkout pushed git revert pushed ``` 不能用checkout C2... 我玩到這裡才發現如果寫錯可以用level和ESC重玩,不用一直看教學畫面。先玩到這裡好了。 ![](https://i.imgur.com/eI5CO1V.png) 3.1 cherry-pick 當你知道你要複製哪些 commit(而且你也知道他們所對應的 hash 值),那麼 git cherry-pick 很適合你。 `git cherry-pick c3 c4 c7` 3.2 git interactive rebase 互動式的 rebase 相當於使用 rebase 這個指令的時候,後面加上一個 -i 的選項。 `git rebase -i HEAD~4` 4.1 ``` git rebase -i HEAD~3 git checkout master git rebase c4' ``` 4.2 為了克服這個困難,我們可以按照下面的方法來做: 先用 git rebase -i 將 commit 重新排序,然後把我們想要修改的 commit 移到最前面 然後用 commit --amend 來進行一些修改 接著再用 git rebase -i 來將他們按照最開始的順序重新排好 最後我們把 master 移到這個修改的最前端(用你自己喜歡的方法),就大功告成啦! 當然還有許多方法可以完成這個任務(我知道你在想 cherry-pick 啦),之後我們會多點關注這些技巧啦,但現在暫時只注意上面這種方法。 啊!最後還要提醒你一下最後所產生的 commit tree,因為我們把 commit 移動了兩次,所以會分別產生一個 apostrophe(單引號) commit。還有一個 apostrophe commit 是因為我們修改 commit 而加進來的。