Git常用命令詳解
Git是一個分散式的版本控制系統,用作Linux內核代碼的管理,Git同樣可以作為部署工具所使用。GitHub的獨特在於從另外一個項目進行分支的簡易性。為一個項目貢獻代碼非常簡單:首先點擊項目站點的「fork」的按鈕,然後將代碼檢出並將修改加入到剛才分出的代碼庫中,最後通過內建的「pull request」機制向項目負責人申請代碼合併。Git也是我們較常用的版本控制服務,下面PHP程序員雷雪松詳細的講解下Git常用命令。
git init在本地新建一個repo,進入一個項目目錄,執行git init,會初始化一個repo,並在當前文件夾下創建一個.git文件夾.git clone
獲取一個url對應的遠程Git repo, 創建一個local copy.一般的格式是git clone [url].clone下來的repo會以url最後一個斜線後面的名稱命名,創建一個文件夾,如果想要指定特定的名稱,可以git clone [url] newname指定.git status
查詢repo的狀態.git status -s: -s表示short, -s的輸出標記會有兩列,第一列是對staging區域而言,第二列是對working目錄而言.git log
show commit history of a branch.git log –oneline –number: 每條log只顯示一行,顯示number條.git log –oneline –graph:可以圖形化地表示出分支合併歷史.git log branchname可以顯示特定分支的log.git log –oneline branch1 ^branch2,可以查看在分支1,卻不在分支2中的提交.^表示排除這個分支(Window下可能要給^branch2加上引號).git log –decorate會顯示出tag信息.git log –author=[author name] 可以指定作者的提交歷史.
git log –since –before –until –after 根據提交時間篩選log.–no-merges可以將merge的commits排除在外.git log –grep 根據commit信息過濾log: git log –grep=keywords默認情況下, git log –grep –author是OR的關係,即滿足一條即被返回,如果你想讓它們是AND的關係,可以加上–all-match的option.git log -S: filter by introduced diff.比如: git log -SmethodName (注意S和後面的詞之間沒有等號分隔).git log -p: show patch introduced at each commit.每一個提交都是一個快照(snapshot),Git會把每次提交的diff計算出來,作為一個patch顯示給你看.另一種方法是git show [SHA].git log –stat: show diffstat of changes introduced at each commit.
同樣是用來看改動的相對信息的,–stat比-p的輸出更簡單一些.git add
在提交之前,Git有一個暫存區(staging area),可以放入新添加的文件或者加入新的改動. commit時提交的改動是上一次加入到staging area中的改動,而不是我們disk上的改動.git add 會遞歸地添加當前工作目錄中的所有文件.git diff
不加參數的git diff:show diff of unstaged changes.此命令比較的是工作目錄中當前文件和暫存區域快照之間的差異,也就是修改之後還沒有暫存起來的變化內容.若要看已經暫存起來的文件和上次提交時的快照之間的差異,可以用:git diff –cached 命令.show diff of staged changes.(Git 1.6.1 及更高版本還允許使用 git diff –staged,效果是相同的).git diff HEAD
show diff of all staged or unstated changes.也即比較woking directory和上次提交之間所有的改動.如果想看自從某個版本之後都改動了什麼,可以用:git diff [version tag]跟log命令一樣,diff也可以加上–stat參數來簡化輸出.git diff [branchA] [branchB]可以用來比較兩個分支.它實際上會返回一個由A到B的patch,不是我們想要的結果.一般我們想要的結果是兩個分支分開以後各自的改動都是什麼,是由命令:git diff [branchA]…[branchB]給出的.實際上它是:git diff $(git merge-base [branchA] [branchB]) [branchB]的結果.
git commit
提交已經被add進來的改動.git commit -m 「the commit message」git commit -a 會先把所有已經track的文件的改動add進來,然後提交(有點像svn的一次提交,不用先暫存). 對於沒有track的文件,還是需要git add一下.git commit –amend 增補提交. 會使用與當前提交節點相同的父節點進行一次新的提交,舊的提交將會被取消.git reset
undo changes and commits.這裡的HEAD關鍵字指的是當前分支最末梢最新的一個提交.也就是版本庫中該分支上的最新版本.git reset HEAD: unstage files from index and reset pointer to HEAD這個命令用來把不小心add進去的文件從staged狀態取出來,可以單獨針對某一個文件操作: git reset HEAD – – filename, 這個- – 也可以不加.git reset –soft
move HEAD to specific commit reference, index and staging are untouched.git reset –hardunstage files AND undo any changes in the working directory since last commit.使用git reset —hard HEAD進行reset,即上次提交之後,所有staged的改動和工作目錄的改動都會消失,還原到上次提交的狀態.這裡的HEAD可以被寫成任何一次提交的SHA-1.不帶soft和hard參數的git reset,實際上帶的是默認參數mixed.總結:git reset –mixed id,是將git的HEAD變了(也就是提交記錄變了),但文件並沒有改變,(也就是working tree並沒有改變). 取消了commit和add的內容.git reset –soft id. 實際上,是git reset –mixed id 後,又做了一次git add.即取消了commit的內容.git reset –hard id.是將git的HEAD變了,文件也變了.
按改動範圍排序如下:soft (commit) < mixed (commit + add) < hard (commit + add + local working)git revert
反轉撤銷提交.只要把出錯的提交(commit)的名字(reference)作為參數傳給命令就可以了.git revert HEAD: 撤銷最近的一個提交.git revert會創建一個反向的新提交,可以通過參數-n來告訴Git先不要提交.git rm
git rm file: 從staging區移除文件,同時也移除出工作目錄.git rm –cached: 從staging區移除文件,但留在工作目錄中.git rm –cached從功能上等同於git reset HEAD,清除了緩存區,但不動工作目錄樹.
git clean
git clean是從工作目錄中移除沒有track的文件.通常的參數是git clean -df:-d表示同時移除目錄,-f表示force,因為在git的配置文件中, clean.requireForce=true,如果不加-f,clean將會拒絕執行.git stash
把當前的改動壓入一個棧.git stash將會把當前目錄和index中的所有改動(但不包括未track的文件)壓入一個棧,然後留給你一個clean的工作狀態,即處於上一次最新提交處.git stash list會顯示這個棧的list.git stash apply:取出stash中的上一個項目(stash@{0}),並且應用於當前的工作目錄.也可以指定別的項目,比如git stash apply stash@{1}.
如果你在應用stash中項目的同時想要刪除它,可以用git stash pop刪除stash中的項目:git stash drop: 刪除上一個,也可指定參數刪除指定的一個項目.git stash clear: 刪除所有項目.git branch
git branch可以用來列出分支,創建分支和刪除分支.git branch -v可以看見每一個分支的最後一次提交.git branch: 列出本地所有分支,當前分支會被星號標示出.git branch (branchname): 創建一個新的分支(當你用這種方式創建分支的時候,分支是基於你的上一次提交建立的).git branch -d (branchname): 刪除一個分支.git checkout
git checkout (branchname) 切換到一個分支.git checkout -b (branchname): 創建並切換到新的分支.這個命令是將git branch newbranch和git checkout newbranch合在一起的結果.checkout還有另一個作用:替換本地改動:git checkout –<filename>此命令會使用HEAD中的最新內容替換掉你的工作目錄中的文件.已添加到暫存區的改動以及新文件都不會受到影響.注意:git checkout filename會刪除該文件中所有沒有暫存和提交的改動,這個操作是不可逆的.git merge
把一個分支merge進當前的分支.git merge [alias]/[branch]把遠程分支merge到當前分支.如果出現衝突,需要手動修改,可以用git mergetool.解決衝突的時候可以用到git diff,解決完之後用git add添加,即表示衝突已經被resolved.git tag
tag a point in history as import.會在一個提交上建立永久性的書籤,通常是發布一個release版本或者ship了什麼東西之後加tag.比如: git tag v1.0git tag -a v1.0, -a參數會允許你添加一些信息,即make an annotated tag.當你運行git tag -a命令的時候,Git會打開一個編輯器讓你輸入tag信息.我們可以利用commit SHA來給一個過去的提交打tag:git tag -a v0.9 XXXXpush的時候是不包含tag的,如果想包含,可以在push時加上–tags參數.fetch的時候,branch HEAD可以reach的tags是自動被fetch下來的, tags that aren』t reachable from branch heads will be skipped.如果想確保所有的tags都被包含進來,需要加上–tags選項.git remote
list, add and delete remote repository aliases.因為不需要每次都用完整的url,所以Git為每一個remote repo的url都建立一個別名,然後用git remote來管理這個list.git remote: 列出remote aliases.如果你clone一個project,Git會自動將原來的url添加進來,別名就叫做:origin.git remote -v:可以看見每一個別名對應的實際url.git remote add [alias] [url]: 添加一個新的remote repo.git remote rm [alias]: 刪除一個存在的remote alias.git remote rename [old-alias] [new-alias]: 重命名.git remote set-url [alias] [url]:更新url. 可以加上—push和fetch參數,為同一個別名set不同的存取地址.git fetch
download new branches and data from a remote repository.可以git fetch [alias]取某一個遠程repo,也可以git fetch –all取到全部repofetch將會取到所有你本地沒有的數據,所有取下來的分支可以被叫做remote branches,它們和本地分支一樣(可以看diff,log等,也可以merge到其他分支),但是Git不允許你checkout到它們.git pull
fetch from a remote repo and try to merge into the current branch.pull == fetch + merge FETCH_HEADgit pull會首先執行git fetch,然後執行git merge,把取來的分支的head merge到當前分支.這個merge操作會產生一個新的commit.如果使用–rebase參數,它會執行git rebase來取代原來的git merge.git rebase
–rebase不會產生合併的提交,它會將本地的所有提交臨時保存為補丁(patch),放在」.git/rebase」目錄中,然後將當前分支更新到最新的分支尖端,最後把保存的補丁應用到分支上.rebase的過程中,也許會出現衝突,Git會停止rebase並讓你解決衝突,在解決完衝突之後,用git add去更新這些內容,然後無需執行commit,只需要:git rebase –continue就會繼續打餘下的補丁.git rebase –abort將會終止rebase,當前分支將會回到rebase之前的狀態.git push
push your new branches and data to a remote repository.git push [alias] [branch]將會把當前分支merge到alias上的[branch]分支.如果分支已經存在,將會更新,如果不存在,將會添加這個分支.如果有多個人向同一個remote repo push代碼, Git會首先在你試圖push的分支上運行git log,檢查它的歷史中是否能看到server上的branch現在的tip,如果本地歷史中不能看到server的tip,說明本地的代碼不是最新的,Git會拒絕你的push,讓你先fetch,merge,之後再push,這樣就保證了所有人的改動都會被考慮進來.git reflog
git reflog是對reflog進行管理的命令,reflog是git用來記錄引用變化的一種機制,比如記錄分支的變化或者是HEAD引用的變化.當git reflog不指定引用的時候,默認列出HEAD的reflog.HEAD@{0}代表HEAD當前的值,HEAD@{3}代表HEAD在3次變化之前的值.git會將變化記錄到HEAD對應的reflog文件中,其路徑為.git/logs/HEAD, 分支的reflog文件都放在.git/logs/refs目錄下的子目錄中.特殊符號:^代表父提交,當一個提交有多個父提交時,可以通過在^後面跟上一個數字,表示第幾個父提交: ^相當於^1.~<n>相當於連續的<n>個^.標籤:Linux運維
來源:Git常用命令詳解推薦閱讀:
※自學Git,有哪些書籍或者好的學習資源?
※git branch 相關操作
※Git 工作流指南
※使用git,用命令好還是客戶端好?
※Git如何在本地查看遠端倉庫超前本地提交的日誌信息?僅僅是日誌信息哦
TAG:Git |