原文地址:zeroturnaround
編譯:FireFrank
原文地址:http://www.freebuf.com/sectool/98396.html
我們這次介紹最成功的源碼管理工具——Git!這是一個非常棒的工具,它使用了擁有強大功能和選項的命令行界面讯赏,這就導(dǎo)致你需要記住并能夠在必要時回憶起這些命令。
如果你和我一樣钢猛,記東西就像負重螞蟻一樣昏昏沉沉,你可能非常需要我們的幫助轩缤!下面命迈,我們將會為你展示一整頁常用git命令,有了它你的工作會變得愉快的多火的。OK壶愤,言歸正傳,你可能已經(jīng)點擊了下面的鏈接查看完整的git命令馏鹤,如果你沒有點擊征椒,你可能缺少了一些冒險精神哦。
現(xiàn)在和我一起開始Git之旅湃累。我們會以一個典型的SSM工作流程為例展示一些最佳做法勃救。下面我們將介紹更多命令的詳情。
我們應(yīng)該從哪里開始治力?
好啦蒙秒,現(xiàn)在課程開始!在最開始的時候宵统,Git創(chuàng)建init并clone晕讲。這兩個命令會從頭開始創(chuàng)建一個能夠管理你源碼的倉庫。這兩個命令當然不同,init
命令用于從scrach創(chuàng)建倉庫瓢省,而clone即字面上的clone弄息,使用該命令把項目從現(xiàn)有的倉庫中復(fù)制到你運行的目錄。一旦完成這些操作勤婚,我們就可以真正的工作流程啦摹量!在ZipRebel項目上有兩個例子:
$ git init myProject
Initialized empty Git repository in /Users/sjmaple/myProject/.git/
clone命令:
$ git clone https://github.com/zeroturnaround/ziprebel.git
Cloning into 'ziprebel'...
remote: Counting objects: 94, done.
remote: Total 94 (delta 0), reused 0 (delta 0), pack-reused 94
Unpacking objects: 100% (94/94), done.
Checking connectivity... done.
Branching
舉個例子,如果我們要創(chuàng)建新功能馒胆,我們應(yīng)該考慮創(chuàng)建一個新的分支(branch)儲存新功能代碼荆永。我覺得這樣做最重要的一點就是保持新功能代碼能夠和舊代碼分離,你可以輕松的從各個分支(branch)轉(zhuǎn)換并且不會污染你的mater代碼国章。所以我們怎么創(chuàng)建分支呢?這點非常容易豆村!只需要使用branch
命令液兽,再起個名字就好啦,如下所示:
$ git branch feature/unzip
在這種情況下掌动,我們需要理智命名四啰,這樣我們就可以通過看branch名稱得知這部分代碼的功能,比如我們?yōu)閆ipRebel項目創(chuàng)建unzip
功能粗恢。雖然這個命令沒有反饋柑晒,但是我們可以使用相同的命令查看所有的分支(branch),這個branch
命令不帶參數(shù):
$ git branch
feature/unzip
* master
我們通過branch
命令還可以做其他事情眷射。首先匙赞,我們可以看到我們新創(chuàng)建的分支,其次妖碉,我們當前處在的活躍分支是master
涌庭,而不是新的分支。順便說一句欧宜,你可以查看所有的分支坐榆,甚至可以通過增加參數(shù)查看遠程分支。我們想要跳到功能/unzip
分支來開始code我們的新功能冗茸,我們使用checkout
命令轉(zhuǎn)換分支:
$ git checkout feature/unzip
Switched to branch 'feature/unzip'
這個命令用于轉(zhuǎn)換分支席镀,更新工作目錄,其代碼基礎(chǔ)不同夏漱。就像我們剛剛創(chuàng)建的分支就沒有任何更新豪诲。
改變的時候到了
現(xiàn)在讓我們更改代碼。我們要使用術(shù)語來解釋并指出一個個狀態(tài)并充分理解這些狀態(tài)麻蹋□烁龋看下面這張圖片:
是不是很漂亮!我們工作目錄中的文件包含所有的文件,而這些文件會被隨時編輯修改芳室,但是事實是直到你執(zhí)行g(shù)it命令之后专肪,這些內(nèi)容才更改。現(xiàn)在讓我們看看你項目中所有文件的狀態(tài)堪侯,使用下面這些已經(jīng)在你腦子中根深蒂固的命令:
$ git status
On branch feature/unzip
nothing to commit, working directory clean
讓我們在工作流上進行一些修改嚎尤,然后看看更新狀態(tài)消息是如何進行的。只要編輯一些文件伍宦,但是只執(zhí)行git status
芽死,結(jié)果如下:
$ git status
On branch feature/unzip
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: src/main/java/org/zeroturnaround/ziprebel/ZipRebel.java
modified: src/test/java/org/zeroturnaround/ziprebel/ZipRebelTest.java
no changes added to commit (use "git add" and/or "git commit -a")
這些內(nèi)容告訴我們我們已經(jīng)修改了一些文件,但是并沒有將修改添加到staging
(staging就是索引)次洼,為下一步commit做好準備关贵。我們接下來使用git add commit
命令將文件單獨或者成組引用添加到staging
,或者stage這些文件卖毁,或者添加一個包含所有修改過文件的wildcard
揖曾。我們現(xiàn)在執(zhí)行后一種操作:
$ git add .
再次執(zhí)行git status
命令,你會看到成功了:
$ git status
On branch feature/unzip
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: src/main/java/org/zeroturnaround/ziprebel/ZipRebel.java
modified: src/test/java/org/zeroturnaround/ziprebel/ZipRebelTest.java
現(xiàn)在我們看到的git承認修改過的文件作為要提交修改的文件亥啦。一頁就可以完成你的版本控制系統(tǒng)的感覺是不是相當不錯炭剪?你會看到在輸出這里的HEAD token
。HEAD
是一個指針或者引用當前分支翔脱。在這一點上奴拦,我們可以通過對文件運行git reset
選擇來unstage
文件,做出進步一修改或者commit我們的修改到本地資源届吁。讓我們執(zhí)行后者:
$ git commit -m "Added unzip capability"
[feature/unzip 05db2cc] Added unzip capability
2 files changed, 2 insertions(+), 2 deletions(-)
如果我們知道只做出了很小的修改不用做出其他commit错妖,我們可以在同一個命令里既執(zhí)行add
操作又執(zhí)行commit。下面的命令就適用于我們已經(jīng)修改了但不在階段環(huán)境中的文件:
$ git commit -am "Added unzip capability"
[feature/unzip 8c10510] Added unzip capability
2 files changed, 2 insertions(+), 2 deletions(-)
-a
標志將添在執(zhí)行commit之前把所有跟蹤文件從工作目錄添加到臨時執(zhí)行疚沐。(請注意站玄,你工作目錄中創(chuàng)建的文件在手動添加之前都不會被追蹤)。等等濒旦,commit是什么意思株旷?這是一個很大的問題!本質(zhì)上一個git commit記錄你的修改快照尔邓,標記你的姓名晾剖、電子郵箱和commit id的commit信息。
在上面的例子中梯嗽,我們拿id 05db2cc 和 8c10510 作為commit自理齿尽。這些可以在之后編碼時遇到故障排除、事故追蹤或故障查明時使用灯节。說到事故追蹤循头,git blame
是一個非常有趣的命令绵估,它在文件中使用關(guān)于誰對代碼做出最后的修改,提交了哪些修改等做出注釋卡骂。這樣可以輸出很多文本国裳,因此考慮使用一個行范圍-L
標志進行限制輸出。
有什么不同呢全跨?
當一個文件的不同內(nèi)容儲存在很多個地方缝左,了解不同位置有什么變化是很重要的。舉個例子浓若,我想知道我的工作區(qū)文件和我的臨時文件有什么區(qū)別渺杉。這里有很多選項可供選擇。事實上挪钓,diff
命令在很多情況下都非常有用是越。我們下面的內(nèi)容會介紹一些diff
命令。
首先碌上,讓我們先思考何如比較你工作目錄和你臨時存儲區(qū)的區(qū)別英妓。做到這點非常容易!只需要輸入git diff
绍赛。如果你想要比較你的本地倉庫和臨時存儲區(qū),你可以使用git diff –cached
辑畦。你甚至可以使用commit ids
比較幾次不同的提交吗蚌,比如:git diff 05db2cc 8c10510
。這是已給非常給力的工具纯出,所以確保使用git diff –help
來查看所有功能選擇最適合你的使用情況蚯妇。
最后,一旦你已經(jīng)完成了新分支的開發(fā)暂筝,你需要把它合并到主分支箩言。所以首先你要進入你想要合并的分支中。在這種情況下焕襟,我們會運行git checkout master
陨收。接下來,我們將進行分支合并工作鸵赖。我們運行git merge feature/unzip
务漩。一切順利的話,我們的代碼會自動合并它褪,我們不需要擔心這件事兒饵骨!但是,合并可能不會一帆風順茫打,可能會出現(xiàn)一些必須解決的沖突居触!git status
命令會幫助你理解哪里存在沖突妖混。如果你打開文件,你會注意到這些標記:<<<<<<<
, >>>>>>>
, 和=======
轮洋,這些標記會圍繞沖突制市,每個分支正在努力完成的修改。
現(xiàn)在砖瞧,我們開始學(xué)習fork
命令啦息堂。我們應(yīng)該做什么呢?你寫好了代碼块促,想要刪除沖突代碼保證進行新的commit提交到主分支荣堰。另外,如果另一個開發(fā)人員寫了一份更棒的代碼竭翠,你可能想要選擇他的代碼進行提交振坚。更可能出現(xiàn)的情況是,你需要創(chuàng)建兩個修改的代碼斋扰,然后把代碼合并到主分支渡八。在任何情況下,你都需要修復(fù)文件传货,之后添加并commit這些更改屎鳍,這樣你才能享受你高潮的解決沖突的能力帶來的美好結(jié)果。
讓我們遠程操作问裕!
目前為止逮壁,包括我們倉庫更改在內(nèi)的所有更改都是本地的。我們甚至不需要提到遠程倉庫粮宛,現(xiàn)在讓我們回到文章最開始的地方窥淆,從git clone
開始將其。在某些階段中巍杈,我們需要同步本地和遠程倉庫忧饭,并且我們需要一些命令幫助我們實現(xiàn)同步:pull
, push
, fetch
。
讓我們從這個問題開始:如果我們有一個過時的本地倉庫會發(fā)生什么筷畦?如果其他人在遠程倉庫中更新了新功能词裤、修復(fù)了bug或者修改了代碼,那我們的本地倉庫肯定過時了鳖宾。我們需要抓住這些變化亚斋,事實上我想要說可以用pull
或者fetch
,但是我不想重新使用這些命令的名稱就能最新最棒的代碼更新我們的本地倉庫攘滩。入侵性最小的方式就是使用fetch
命令帅刊,它會從遠程倉庫中抓起所有最近的commit,然后把這些導(dǎo)入到同一個遠程反之中漂问。
但是值得注意的是赖瞒,fetch
并不會把這些commit添加到你工作空間的本地branch中女揭,你可以使用之前提到的git branch -av
命令查看遠程分支。你在這里還可以選擇手動合并分支栏饮“赏茫或者,使用git pull –rebase
命令袍嬉,它會先執(zhí)行git fetch
命令境蔼,再執(zhí)行git rebase
命令。但是媽個雞伺通,什么是rebase箍土?它是一種機制,這種機制允許你在傳入的commit頂部應(yīng)用本地commit罐监,而不是簡單的平行的兩條線合并吴藻。
最后,我們介紹一下push
命令弓柱,它是fetch
的對立命令沟堡。我們只是簡單的從我們的本地倉庫把代碼傳到遠程倉庫。注意矢空,總有一些文件會被重寫航罗,千萬小心!
總結(jié)
希望這些命令解釋能對你有用屁药。我們很希望得到你的git技巧哦粥血,在評論中寫下你的技巧和竅門吧!