[!NOTE]
當安裝完 Git 應該作的第一件事就是設置你的用戶名稱與郵件地址。 這樣作很重要,由於每個 Git 的提交都會使用這些信息,而且它會寫入到你的每一次提交中,不可更改。css
git config --global user.name "huyaocode" git config --global user.email johndoe@example.com
git add 文件名或路徑
建立一個.gitignore
文件,可描述須要忽略的文件。 參考html
# no .a files *.a # but do track lib.a, even though you're ignoring .a files above !lib.a # 只忽略當前文件夾下已 TODO 爲名的文件 /TODO # 忽略當前目錄下 build 這個文件夾 build/ # ignore doc/notes.txt, but not doc/server/arch.txt doc/*.txt # ignore all .pdf files in the doc/ directory doc/**/*.pdf
git status -s
將每一個修改狀態以一行展現,也能夠用git status
多行展現。git
A
新添加到暫存區中的文件M
修改過的文件D
被刪除的文件MM
出如今右邊的 M 表示該文件被修改了可是還沒放入暫存區,出如今靠左邊的 M 表示該文件被修改了並放入了暫存區。??
未跟蹤git diff
git diff --cached
或 git diff --staged
運行git commit
,會出現以下狀況。這種方式會啓動文本編輯器,開頭還有一空行,供你輸入提交說明。下面的行是被註釋了的,也能夠取消這些註釋。github
通常是vim 或 emacs。固然也能夠按照 起步 介紹的方式,使用 git config --global core.editor
命令設定你喜歡的編輯軟件。數據庫
也可使用git commit -m "修改描述"
這種直接輸入描述的方式提交修改。vim
git commit
加上 -a
選項,Git 就會自動把全部已經跟蹤過的文件暫存起來一併提交,從而跳過 git add 步驟安全
要從 Git 中移除某個文件,就必需要從已跟蹤文件清單中移除(確切地說,是從暫存區域移除),而後提交。
能夠用 git rm 命令完成此項工做,並連帶從工做目錄中刪除指定的文件,這樣之後就不會出如今未跟蹤文件清單中了。服務器
運行 git rm
記錄這次移除文件的操做。下一次提交時,該文件就再也不歸入版本管理了。 若是刪除以前修改過而且已經放到暫存區域的話,則必需要用強制刪除選項 -f
(譯註:即 force 的首字母)。 這是一種安全特性,用於防止誤刪尚未添加到快照的數據,
這樣的數據不能被 Git 恢復。編輯器
想把文件從 Git 倉庫中刪除(亦即從暫存區域移除),但仍然但願保留在當前工做目錄中。(不想讓Git跟蹤)學習
git rm --cached 某文件
git mv file_from file_to
其實,運行 git mv 就至關於運行了下面三條命令:
mv README.md README git rm README.md git add README
[!NOTE]
git log
git log 會按提交時間列出全部的更新,最近的更新排在最上面。 正如你所看到的,這個命令會列出每一個提交的 SHA-1 校驗和、做者的名字和電子郵件地址、提交時間以及提交說明。
使用 -p
用來限制展現條數。git log -p -2
使用 --stat
選項看到每次提
使用format
,定製要顯示的記錄格式。
使用--graph
可形象地展現你的分支、合併歷史。
$ git log --pretty=format:"%h %s" --graph * 2d3acf9 ignore errors from SIGCHLD on trap * 5e3ee11 Merge branch 'master' of git://github.com/dustin/grit |\ | * 420eac9 Added a method for getting the current branch. * | 30e367c timeout code and tests * | 5a09431 add timeout protection to grit * | e1193f8 support for heads with slashes in them |/ * d6016bc require time for xmlschema * 11d191e Merge branch 'defunkt' into local
[!NOTE]
有時候咱們提交完了才發現漏掉了幾個文件沒有添加,或者提交信息寫錯了。 此時,能夠運行帶有--amend
選項的提交命令嘗試從新提交。
git commit --amend
這個命令會將暫存區中的文件提交。 若是自上次提交以來你還未作任何修改(例如,在上次提交後立刻執行了此命令),那麼快照會保持不變,而你所修改的只是提交信息。
文本編輯器啓動後,能夠看到以前的提交信息。 編輯後保存會覆蓋原來的提交信息。
例如,你提交後發現忘記了暫存某些須要的修改,能夠像下面這樣操做:
git commit -m 'initial commit' git add forgotten_file git commit --amend
最終你只會有一個提交 - 第二次提交將代替第一次提交的結果。
使用 git reset HEAD <file>
來取消暫存。在調用時加上 --hard 選項能夠令 git reset 成爲一個危險的命令(譯註:可能致使工做目錄中全部當前進度丟失!)
使用git checkout -- <file>
能夠撤銷修改(未保存到暫存區)
簡單來講,git pull 是 git fetch + git merge。
當你使用 pull,Git 會試着自動爲你完成工做。它是上下文(工做環境)敏感的,因此 Git 會把全部拉取的提交合併到你當前處理的分支中。pull 則是 自動合併提交而沒有讓你複查的過程。若是你沒有細心管理你的分支,你可能會頻繁遇到衝突。
當你 fetch,Git 會收集目標分支中的全部不存在的提交,並將這些提交存儲到本地倉庫中。但Git 不會把這些提交合併到當前分支中。這種處理邏輯在當你須要保持倉庫更新,在更新文件時又但願處理可能中斷的事情時,這將很是實用。而將提交合併到主分支中,則該使用 merge。
假設你的情形是這樣,其中 C 是你的 HEAD,(F) 是你文件的狀態。
(F) A-B-C ↑ master (F) A-B-C ↑ master 要修改提交中的更改: git reset --hard HEAD~1 1 git reset --hard HEAD~1 如今B是 HEAD,由於你使用了 --hard,因此你的文件將重置到提交 B 時的狀態。 要撤銷提交但保留更改: git reset HEAD~1 1 git reset HEAD~1 如今咱們告訴 Git 將 HEAD 指針移回(後移)一個提交(B),並保留文件原樣,而後你能夠 git status 來顯示你已經檢入 C 的更改。 撤銷提交但保留文件和索引: git reset --soft HEAD~1 1 git reset --soft HEAD~1 執行此操做後,git status,你講看到索引中的文件跟之前一致。
[!NOTE]
命令 git cherry-pick 一般用於把特定提交從存儲倉庫的一個分支引入到其餘分支中。常見的用途是從維護的分支到開發分支進行向前或回滾提交。
這與其餘操做(例如:合併(merge)、變基(rebase))造成鮮明對比,後者一般是把許多提交應用到其餘分支中。
小結:
git cherry-pick <commit-hash> 1 git cherry-pick <commit-hash>
Forking 工做流程 與其餘流行的 Git 工做流程有着根本的區別。它不是用單個服務端倉庫充當「中央」代碼庫,而是爲每一個開發者提供本身的服務端倉庫。Forking 工做流程最經常使用於公共開源項目中。
Forking 工做流程的主要優勢是能夠聚集提交貢獻,又無需每一個開發者提交到一箇中央倉庫中,從而實現乾淨的項目歷史記錄。開發者能夠推送(push)代碼到本身的服務端倉庫,而只有項目維護人員才能直接推送(push)代碼到官方倉庫中。
當開發者準備發佈本地提交時,他們的提交會推送到本身的公共倉庫中,而不是官方倉庫。而後他們向主倉庫提交請求拉取(pull request),這會告知項目維護人員有能夠集成的更新。
[!NOTE]
Gitflow 工做流程使用兩個並行的、長期運行的分支來記錄項目的歷史記錄,分別是 master 和 develop 分支。
[!NOTE]
git stash 命令把你未提交的修改(已暫存(staged)和未暫存的(unstaged))保存以供後續使用,之後就能夠從工做副本中進行還原。
回顧:
$ git status On branch master Changes to be committed: new file: style.css Changes not staged for commit: modified: index.html $ git stash Saved working directory and index state WIP on master: 5002d47 our new homepage HEAD is now at 5002d47 our new homepage $ git status On branch master nothing to commit, working tree clean $ git status On branch master Changes to be committed: new file: style.css Changes not staged for commit: modified: index.html $ git stash Saved working directory and index state WIP on master: 5002d47 our new homepage HEAD is now at 5002d47 our new homepage $ git status On branch master nothing to commit, working tree clean 咱們可使用暫存(stash)的一個地方是,若是咱們發如今上次提交中忘記了某些內容,而且已經開始在同一分支中處理下一個提交了: # Assume the latest commit was already done # start working on the next patch, and discovered I was missing something # stash away the current mess I made $ git stash save # some changes in the working dir # and now add them to the last commit: $ git add -u $ git commit --ammend # back to work! $ git stash pop # Assume the latest commit was already done # start working on the next patch, and discovered I was missing something # stash away the current mess I made $ git stash save # some changes in the working dir # and now add them to the last commit: $ git add -u $ git commit --ammend # back to work! $ git stash pop
若是你在 git add 過程當中誤操做,你最終會添加不想提交的文件。可是,git rm 則會把你的文件從你暫存區(索引)和文件系統(工做樹)中刪除,這可能不是你想要的。
換成 git reset 操做:
git reset filename # or
echo filename >> .gitingore # add it to .gitignore to avoid re-adding it
1
2
git reset filename # or
echo filename >> .gitingore # add it to .gitignore to avoid re-adding it
上面意思是,git reset
[!NOTE]
這兩個命令都是把修改從一個分支集成到另外一個分支上,它們只是以很是不一樣的方式進行。
考慮一下場景,在合併和變基前:
A <- B <- C [master]
^
D <- E [branch]
1
2
3
4
A <- B <- C [master]
^
D <- E [branch]
在 git merge master 以後:
A <- B <- C
^ ^
D <- E <- F
1
2
3
4
A <- B <- C
^ ^
D <- E <- F
在 git rebase master 以後:
A <- B <- C <- D <- E
1
A <- B <- C <- D <- E
使用變基時,意味着使用另外一個分支做爲集成修改的新基礎。
若是你對修改不夠果斷,請使用合併操做。
根據你但願的歷史記錄的樣子,而選擇使用變基或合併操做。
參考資料