開發指南之Git命令的最佳實踐技巧

原文地址:zeroturnaround
編譯:FireFrank
原文地址:http://www.freebuf.com/sectool/98396.html

我們這次介紹最成功的源碼管理工具——Git!這是一個非常棒的工具,它使用了擁有強大功能和選項的命令行界面,這就導致你需要記住并能夠在必要時回憶起這些命令。

如果你和我一樣,記東西就像負重螞蟻一樣昏昏沉沉,你可能非常需要我們的幫助!下面,我們將會為你展示一整頁常用git命令,有了它你的工作會變得愉快的多。OK,言歸正傳,你可能已經點擊了下面的鏈接查看完整的git命令,如果你沒有點擊,你可能缺少了一些冒險精神哦。

現在和我一起開始Git之旅。我們會以一個典型的SSM工作流程為例展示一些最佳做法。下面我們將介紹更多命令的詳情。

我們應該從哪里開始?

好啦,現在課程開始!在最開始的時候,Git創建init并clone。這兩個命令會從頭開始創建一個能夠管理你源碼的倉庫。這兩個命令當然不同,init命令用于從scrach創建倉庫,而clone即字面上的clone,使用該命令把項目從現有的倉庫中復制到你運行的目錄。一旦完成這些操作,我們就可以真正的工作流程啦!在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

舉個例子,如果我們要創建新功能,我們應該考慮創建一個新的分支(branch)儲存新功能代碼。我覺得這樣做最重要的一點就是保持新功能代碼能夠和舊代碼分離,你可以輕松的從各個分支(branch)轉換并且不會污染你的mater代碼。所以我們怎么創建分支呢?這點非常容易!只需要使用branch命令,再起個名字就好啦,如下所示:

$ git branch feature/unzip

在這種情況下,我們需要理智命名,這樣我們就可以通過看branch名稱得知這部分代碼的功能,比如我們為ZipRebel項目創建unzip功能。雖然這個命令沒有反饋,但是我們可以使用相同的命令查看所有的分支(branch),這個branch命令不帶參數:

$ git branch
  feature/unzip
* master

我們通過branch命令還可以做其他事情。首先,我們可以看到我們新創建的分支,其次,我們當前處在的活躍分支是master,而不是新的分支。順便說一句,你可以查看所有的分支,甚至可以通過增加參數查看遠程分支。我們想要跳到功能/unzip分支來開始code我們的新功能,我們使用checkout命令轉換分支:

$ git checkout feature/unzip
Switched to branch 'feature/unzip'

這個命令用于轉換分支,更新工作目錄,其代碼基礎不同。就像我們剛剛創建的分支就沒有任何更新。

改變的時候到了

現在讓我們更改代碼。我們要使用術語來解釋并指出一個個狀態并充分理解這些狀態。看下面這張圖片:

是不是很漂亮!我們工作目錄中的文件包含所有的文件,而這些文件會被隨時編輯修改,但是事實是直到你執行git命令之后,這些內容才更改。現在讓我們看看你項目中所有文件的狀態,使用下面這些已經在你腦子中根深蒂固的命令:

$ git status
On branch feature/unzip
nothing to commit, working directory clean

讓我們在工作流上進行一些修改,然后看看更新狀態消息是如何進行的。只要編輯一些文件,但是只執行git status,結果如下:

$ 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")

這些內容告訴我們我們已經修改了一些文件,但是并沒有將修改添加到staging(staging就是索引),為下一步commit做好準備。我們接下來使用git add commit命令將文件單獨或者成組引用添加到staging,或者stage這些文件,或者添加一個包含所有修改過文件的wildcard。我們現在執行后一種操作:

$ git add .

再次執行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

現在我們看到的git承認修改過的文件作為要提交修改的文件。一頁就可以完成你的版本控制系統的感覺是不是相當不錯?你會看到在輸出這里的HEAD tokenHEAD是一個指針或者引用當前分支。在這一點上,我們可以通過對文件運行git reset選擇來unstage文件,做出進步一修改或者commit我們的修改到本地資源。讓我們執行后者:

$ git commit -m "Added unzip capability"
[feature/unzip 05db2cc] Added unzip capability
 2 files changed, 2 insertions(+), 2 deletions(-)

如果我們知道只做出了很小的修改不用做出其他commit,我們可以在同一個命令里既執行add操作又執行commit。下面的命令就適用于我們已經修改了但不在階段環境中的文件:

$ git commit -am "Added unzip capability"
[feature/unzip 8c10510] Added unzip capability
 2 files changed, 2 insertions(+), 2 deletions(-)

-a標志將添在執行commit之前把所有跟蹤文件從工作目錄添加到臨時執行。(請注意,你工作目錄中創建的文件在手動添加之前都不會被追蹤)。等等,commit是什么意思?這是一個很大的問題!本質上一個git commit記錄你的修改快照,標記你的姓名、電子郵箱和commit id的commit信息。

在上面的例子中,我們拿id 05db2cc 和 8c10510 作為commit自理。這些可以在之后編碼時遇到故障排除、事故追蹤或故障查明時使用。說到事故追蹤,git blame是一個非常有趣的命令,它在文件中使用關于誰對代碼做出最后的修改,提交了哪些修改等做出注釋。這樣可以輸出很多文本,因此考慮使用一個行范圍-L標志進行限制輸出。

有什么不同呢?

當一個文件的不同內容儲存在很多個地方,了解不同位置有什么變化是很重要的。舉個例子,我想知道我的工作區文件和我的臨時文件有什么區別。這里有很多選項可供選擇。事實上,diff命令在很多情況下都非常有用。我們下面的內容會介紹一些diff命令。

首先,讓我們先思考何如比較你工作目錄和你臨時存儲區的區別。做到這點非常容易!只需要輸入git diff。如果你想要比較你的本地倉庫和臨時存儲區,你可以使用git diff –cached。你甚至可以使用commit ids比較幾次不同的提交,比如:git diff 05db2cc 8c10510。這是已給非常給力的工具,所以確保使用git diff –help來查看所有功能選擇最適合你的使用情況。

最后,一旦你已經完成了新分支的開發,你需要把它合并到主分支。所以首先你要進入你想要合并的分支中。在這種情況下,我們會運行git checkout master。接下來,我們將進行分支合并工作。我們運行git merge feature/unzip。一切順利的話,我們的代碼會自動合并,我們不需要擔心這件事兒!但是,合并可能不會一帆風順,可能會出現一些必須解決的沖突!git status命令會幫助你理解哪里存在沖突。如果你打開文件,你會注意到這些標記:<<<<<<<, >>>>>>>, 和=======,這些標記會圍繞沖突,每個分支正在努力完成的修改。

現在,我們開始學習fork命令啦。我們應該做什么呢?你寫好了代碼,想要刪除沖突代碼保證進行新的commit提交到主分支。另外,如果另一個開發人員寫了一份更棒的代碼,你可能想要選擇他的代碼進行提交。更可能出現的情況是,你需要創建兩個修改的代碼,然后把代碼合并到主分支。在任何情況下,你都需要修復文件,之后添加并commit這些更改,這樣你才能享受你高潮的解決沖突的能力帶來的美好結果。

讓我們遠程操作!

目前為止,包括我們倉庫更改在內的所有更改都是本地的。我們甚至不需要提到遠程倉庫,現在讓我們回到文章最開始的地方,從git clone開始將其。在某些階段中,我們需要同步本地和遠程倉庫,并且我們需要一些命令幫助我們實現同步:pull, push, fetch

讓我們從這個問題開始:如果我們有一個過時的本地倉庫會發生什么?如果其他人在遠程倉庫中更新了新功能、修復了bug或者修改了代碼,那我們的本地倉庫肯定過時了。我們需要抓住這些變化,事實上我想要說可以用pull或者fetch,但是我不想重新使用這些命令的名稱就能最新最棒的代碼更新我們的本地倉庫。入侵性最小的方式就是使用fetch命令,它會從遠程倉庫中抓起所有最近的commit,然后把這些導入到同一個遠程反之中。

但是值得注意的是,fetch并不會把這些commit添加到你工作空間的本地branch中,你可以使用之前提到的git branch -av命令查看遠程分支。你在這里還可以選擇手動合并分支。或者,使用git pull –rebase命令,它會先執行git fetch命令,再執行git rebase命令。但是媽個雞,什么是rebase?它是一種機制,這種機制允許你在傳入的commit頂部應用本地commit,而不是簡單的平行的兩條線合并。

最后,我們介紹一下push命令,它是fetch的對立命令。我們只是簡單的從我們的本地倉庫把代碼傳到遠程倉庫。注意,總有一些文件會被重寫,千萬小心!

總結

希望這些命令解釋能對你有用。我們很希望得到你的git技巧哦,在評論中寫下你的技巧和竅門吧!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 1. 安裝 Github 查看是否安裝git: $ git config --global user.name "...
    Albert_Sun閱讀 13,721評論 9 163
  • 1.git的安裝 1.1 在Windows上安裝Git msysgit是Windows版的Git,從https:/...
    落魂灬閱讀 12,716評論 4 54
  • 今天風很靜,天很藍 我和你道別 在這快樂的圣誕節 作者簡介: 作者lucky幸運草,我國首期KSS家棋館館主,廣東...
    幸運暖茶閱讀 201評論 2 2
  • 村口的古柳下 深埋著未完的游戲 河邊的蘆葦叢中 潛伏著聲聲竊笑 月倚墻 墻下一株株恬靜的月光 把你和往事窖藏 釀成...
    君莫譚閱讀 163評論 2 1
  • 從團建活動里偷偷提前撤退,菲露站在路邊打開手機,地圖顯示最近的地鐵站3公里,公交車只一路,附近沒有出租車,沒有專車...
    彈舞聲閱讀 193評論 0 0