git 使用筆記

本文檔主要記錄 git 平常高頻使用命令。git

本地倉庫由 git 維護的三棵「樹」組成。
第一個是工做目錄,它持有實際文件;
第二個是暫存區(Index),它像個緩存區域,臨時保存改動;
最後是 HEAD,它指向你最後一次提交的結果。
以下圖所示,shell

新建

  1. git init,建立一個新的本地倉庫。
  2. git clone -b <遠端分支名> <url> <local-name>,從遠端 url 拉取倉庫拉取制定分支到本地 local-name 文件夾下,若是不加遠端分支名,則爲默認分支 master。

提交

  1. git add <file1> <file2> ... 將 working dir 相應文件的更改提交到 index 中。
  2. git add . 提交全部文件的更改。
  3. git commit -m 'cmmit xx' 將 index 中的內容提交到本地倉庫,HEAD 指向最新提交。
  4. git commit -a -m 'commit xx' 將 working dir 全部更改一次性提交到本地倉庫。
  5. git commmit 做用同 3,可是會彈出窗口,支持更長的 commit 信息。
  6. git push <上游> <上游分支> 代碼提交到遠端庫。

commit 信息變動

  1. git commit --amend 進入編輯器,修改上一次的 commit 信息。
  2. git rebase -i <commitid> 合併 commit。

舉例說明,使用 git log 查看,有如下 4 個 commit,緩存

commit C4
Date:   Sun Jun 21 17:25:56 2020 +0800
    add line11

commit C3
Date:   Sun Jun 21 17:24:33 2020 +0800
    add line10

commit C2
Date:   Sun Jun 21 11:49:06 2020 +0800
    add line1
    commbine 1

commit C1
Date:   Sun Jun 21 11:45:06 2020 +0800
    add newfile

如今,我想要將 C2 和 C3 合併,那麼找到最先的 commit C2 的上一個 C1(或者使用 C2^),執行 git rebase -i C1,會出現合併 commit 選擇的頁面,大概以下,編輯器

pick C2 add line1
pick C3 add line10
pick C4 add line11

# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit

根據命令說明,將要合併的 commit 前面的命令改爲 f 或者 s, 二者的區別的是 f 在編輯合併後 commit的信息時只會出現最後一條,而 s 都會保存,建議使用 s 。要合併 C2 和 C3 的話,那麼選擇時間早的 C2,因此把 C3 前的 pick 改成 s,保存。post

接着會出現編輯頁,編輯合併後 commit 的提交信息,改好之後再次保存就可。this

注意:要合併的 C2 和 C3 是連續的 commit。url

撤銷

  1. git checkout -- <file> 撤銷一個工做區文件(必須是已經被 track 的文件)的修改。<file> 參數爲 . 時表示撤銷全部修改。
  2. git rm --cached <file> 從 index 中刪除一個文件,使之變爲 Untracked files 狀態。
  3. git reset HEAD <file> 從 index 中撤銷一個更改。
  4. git reset --soft <commitid> 從本地倉庫 HEAD 回滾到 index 區(未 commit 的狀態)。
  5. git reset --mixed <commitid> 從本地倉庫 HEAD 回滾到工做區(未 add 的狀態)。
  6. git reset --hard <commitid> 從本地倉庫 HEAD 作版本回退(工做區未更改,已提交)。
  7. git revert --no-commit <commit1>..<commit2> 撤銷指定 cimmit 的代碼提交。
    撤銷從 commit1 到 commit2 的提交,區間前開後閉區間。--no-commit 表示能夠最後一塊兒手動 git commit 提交。
    revert 實際上是將要取消的提交記錄按照相反的操做將他們抵消掉,而後從新生成一個提交記錄,這樣在提交記錄的完整性上更好,不一樣於 reset 的直接抹掉。
    有衝突時須要手動修復,add 後再次 continue。
  8. git merge --abort 拋棄合併過程而且嘗試重建合併前的狀態。該命令僅僅在合併後致使衝突時才使用

分支管理

  1. git checkout -b <banch name> <base branch> 基於 base 分支建立一個新分支,並切到新分支。base 分支爲空時,表示爲當前分支,base 分支若是爲遠端分支,則要加上游分支名字,如 origin/dev
  2. git checkout <branch name> 切到某分支。
  3. git branch -a 查看全部分支。

代碼 diff

  1. git diff <commit1> <commit2> <filename> 比較 file 在兩個版本以前的差別。
    若是不加 filename,那麼比較全部文件的差別,
    若是隻有一個 commitid,表示指定 commitid 與當前版本的差別。
    若是沒有 commitid,只有 filename,比較某個文件與 HEAD 中的差別。
    若是後面什麼參數也沒有,表示與 HEAD 的全部差別。
  2. git diff --staged/--cached 比較暫存區/工做區與上一次提交的差別。

刪除文件/分支

  1. git branch -d <branch name> 刪除本地分支。
  2. git push origin --delete <branch name> 刪除遠端分支。
  3. git rm --cached <file> 並進行提交,完成本地文件在遠端的刪除。

代碼合併

  1. git merge <feature> <master> 在 feature 上合併 master(這可能出現衝突,須要自行解決),
    若是參數只有一個 branch,則表示與當前分支合併。

    feature 分支每次須要合併上游更改時,它都將產生一個額外的合併提交。若是master 提交很是活躍,這可能會嚴重污染你的 feature 分支歷史記錄spa

  2. git rebase -i <branch name> 交互式合併指定分支。

rebase 經過爲原始分支中的每一個提交建立全新的 commits 來 重寫 項目歷史記錄。
rebase 的主要好處是能夠得到更清晰的項目歷史。
在提交拉取請求以前,一般使用交互式 rebase 清理代碼一般是個好的辦法,可是在別人使用的分支(公共分支)上進行 rebase,重寫其歷史記錄將使 Git 和你的隊友沒法跟蹤添加到該功能的任何後續提交,也會在別人拉取代碼時產生衝突
在你運行 git rebase 命令以前,老是問本身,還有其餘人在用這個分支嗎? 若是答案是確定的,那就把你的手從鍵盤上移開,開始考慮採用非破壞性的方式進行改變(例如,git merge 命令)。不然,你能夠爲所欲爲地重寫歷史記錄。3d

  1. git cherry-pick <commitid1>..<commitid2> 從 commitid1(不包括)到 commitid2 的更改,應用到本分支,若是要包含 commitid1,則使用 commitid1^

好的實踐

永遠不要在公共分支上使用 git rebase
在私人分支,rebase 修改我的本次功能的 commit,經過按期執行交互式 rebase,你能夠確保功能中的每一個提交都具備針對性和意義。而後 merge 到主分支上。rest

更多參考 《git rebase VS git merge? 更優雅的 git 合併方式值得擁有

代碼拉取

git pull <上游> <上游分支> 從上游拉取指定分支。
若是上游分支與本地分支存在交叉,就會出現 Merge branch 'xx' of xx into xxx 的自動 commit,因此最好在使用 git pull 命令時,後面加上 --rebase 選項
若是拉取不產生衝突,會直接 rebase,不會產生分支合併操做,若是有衝突則須要手動 fix 後,自行合併。

注意:以上全部使用 commitid 的地方,也均可以使用 HEAD/ HEAD^/HEAD~3 這種方式。

相關文章
相關標籤/搜索