GITHUB筆記

現在總結一下今天學的兩點內容:

初始化一個Git倉庫,使用git init命令。

添加文件到Git倉庫,分兩步:

  • 第一步,使用命令git add <file>,注意,可反覆多次使用,添加多個文件;

  • 第二步,使用命令git commit,完成。

  • 小結

    • 要隨時掌握工作區的狀態,使用git status命令。

    • 如果git status告訴你有文件被修改過,用git diff可以查看修改內容。

    一個文件要分兩步來提交。add、在commit。 如果你修改了。那麼可以通過git diff來查看內容。

  • 如果你修改了新的內容,但是沒有提交commit,那麼git status的時候就會有問題

$ mkdir learngit //創建一個文件夾
$ cd learngit 進入這個文件夾

$ pwd
/c/Users/adminstration/learngit //顯示文件夾的路徑

$ git init //把這個文件夾當成本地庫
Initialized empty Git repository in C:/Users/adminstration/learngit/.git/

$ git add new1.txt //把new1.txt文件add進去
$git rm new1.txt //刪除某個文件
$ git commit -m "..." //把add的文件都commit出去 "..." 裏面的內容是 註釋.相當於每次提交都會有一個備註。
$ cat new1.txt //顯示cat的內容
$ git diff new1.txt //這個只能是沒有add的文件,顯示 沒有add的文件,和已經commit的文件的區別
$ git log //顯示commit的日誌
commit 618d0be8843a3e5f3053ac50b76e64d0ad41131a (HEAD -> master)
Author: q139861200 <[email protected]>
Date:   Wed Sep 27 19:55:51 2017 +0800


   

Git必須知道當前版本是哪個版本,在Git中,用HEAD表示當前版本,也就是最新的提交3628164...882e1e0(注意我的提交ID和你的肯定不一樣),上一個版本就是HEAD^,上上一個版本就是HEAD^^,當然往上100個版本寫100個^比較容易數不過來,所以寫成HEAD~100

現在,我們要把當前版本“append GPL”回退到上一個版本“add distributed”,就可以使用git reset命令:

$ git reset --hard HEAD^
HEAD is now at ea34578 add distributed
.


commit 77773cdcbf09546f77b4a9c52a249a2cdce7aa78
Author: q139861200 <[email protected]>
Date:   Wed Sep 27 17:47:55 2017 +0800


    changed to be committed


commit 6f12941ed0c25873d46c3ffce0f0ee3c1515a04a
Author: q139861200 <[email protected]>
Date:   Wed Sep 27 17:32:53 2017 +0800


    my first file committed


現在,我們要把當前版本“append GPL”回退到上一個版本“add distributed”,就可以使用git reset命令:

$ git reset --hard HEAD^
HEAD is now at ea34578 add distributed
$ git reset --hard 618d0be8843a3e5f3053ac50b76e64d0ad41131a    到了過去某個版本就不能在到之前的最新版本了,只能用之前用git  log查找的序列號來回到之前。
$ git reflog //來查找之前的序列號

$ git checkout LICENSE.txt //如果之前已經commit了, 但是你在 工作區裏面做了很多修改,那麼就用這,把工作區的東西還原跟commit一樣。如果有 緩存區,那麼就優先還原緩衝區裏面

git reset HEAD LICENSE.txt //把暫存區的內容取消,保留工作區的內容

git rm LICENSE.txt //會把你工作區的文件刪除,並且會把這個刪除的信息發送到 暫存區。如果要還原,先把暫存區的內容清除,用上面的命令。
在用git checkout LICENSE.txt 還原

$ git remote add origin git@github.com:michaelliao/learngit.git   //把本地的倉庫和網上的關聯起來  這裏的origin是 遠程倉庫的名字,這個名字是相對於本地倉庫來說的,githu網站上面遠程倉庫的名字也許並不是這個名字。

$ git push origin master  //這裏面的origin是相對於本地倉庫對 關聯的遠程倉庫的名字( 實際的名字是以github網站上面的爲準)
推送本地內容推送到   master遠程


$ git clone git@github.com:michaelliao/gitskills.git        //michaelliao是你的賬號,後面gitskills是具體的倉庫
  把一個github網上的倉庫克隆一個到本地。

$ git checkout -b dev
Switched to a new branch 'dev'

git checkout命令加上-b參數表示創建並切換,相當於以下兩條命令:

$ git branch dev
$ git checkout dev
Switched to branch 'dev'

然後,用git branch命令查看當前分支:

$ git branch
* dev
  master
  //如果你在某個分支改了一個commit的內容,如果你換了個分支,那麼文件夾裏面的內容會是之前那個分支的內容。 你在換分支,那麼文件夾裏面的內容就會變過來。


$ git merge dev   把dev的內容合併到當前分支。也就是覆蓋當前分支的內容。
git branch -d <name>  刪除某個分支


git-br-conflict-merged

修復bug時,我們會通過創建新的bug分支進行修復,然後合併,最後刪除;

當手頭工作沒有完成時,先把工作現場git stash一下,然後去修復bug,修復後,再git stash pop,回到工作現場。


git remote -v顯示遠程倉庫的詳細信息
git remote remove origin //刪除這個遠程倉庫

$ git push origin master

如果要推送其他分支,比如dev,就改成:

$ git push origin dev
$ git clone git@github.com:michaelliao/learngit.git  //如果github上面的這個倉庫裏面有分支,那麼你clone下來之後是看不到這個分支的。
$ git checkout -b dev origin/dev    //創建一個dev,和遠程的dev關聯起來。  這份本地的分支要跟遠程的分支同名。
$ git push origin dev  //origin是遠程倉庫,dev是遠程分支。
<<<<<<< HEAD
1
=======
2
>>>>>>> b4f33a1012c1e15cdc63b62f9ac97c17d5b5debe
// HEAD表示你本地有,遠程倉庫沒有的, ======= 下面表示本地沒有,遠程倉庫有的內容



git pull也失敗了,原因是沒有指定本地dev分支與遠程origin/dev分支的鏈接,根據提示,設置devorigin/dev的鏈接:

$ git branch --set-upstream dev origin/dev

因此,多人協作的工作模式通常是這樣:

  1. 首先,可以試圖用git push origin branch-name推送自己的修改;

  2. 如果推送失敗,則因爲遠程分支比你的本地更新,需要先用git pull試圖合併;

  3. 如果合併有衝突,則解決衝突,並在本地提交;

  4. 沒有衝突或者解決掉衝突後,再用git push origin branch-name推送就能成功!

如果git pull提示“no tracking information”,則說明本地分支和遠程分支的鏈接關係沒有創建,用命令git branch --set-upstream branch-name origin/branch-name

這就是多人協作的工作模式,一旦熟悉了,就非常簡單。

小結

  • 查看遠程庫信息,使用git remote -v

  • 本地新建的分支如果不推送到遠程,對其他人就是不可見的;

  • 從本地推送分支,使用git push origin branch-name,如果推送失敗,先用git pull抓取遠程的新提交;

  • 在本地創建和遠程分支對應的分支,使用git checkout -b branch-name origin/branch-name,本地和遠程分支的名稱最好一致;

  • 建立本地分支和遠程分支的關聯,使用git branch --set-upstream branch-name origin/branch-name

  • 從遠程抓取分支,使用git pull,如果有衝突,要先處理衝突。


本地master只能跟遠程master 對應, 分支的內容 上傳 也只會跟  遠程的分支 來對應起來。不會混着搞
















===============================================
另一位博客

1. 用線上版本強制覆蓋本地代碼

有時候本地調試、debug,本地代碼已經改的一團糟了;或者線上功能好使,而本地功能不好使,希望用線上代碼強制覆蓋本地代碼,git命令如下:

git fetch --all                     //獲取線上所有分支的的代碼
git reset --hard origin/master      //使用遠程(origin)master分支的代碼覆蓋本地代碼
  • 1
  • 2
  • 3

注意:此命令與git checkout . 的區別,checkout是放棄本地修改,將代碼回退到本地版本庫最新版本,reset是放棄本地修改,將本地代碼回退到線上最新版本

=========================================================之前的筆記
第一步,我們先新建一個文件夾,在文件夾裏新建一個文件(我是用 Linux 命令去新建的,Windows用戶可以自己手動新建)


mkdir test (創建文件夾test) cd test (切換到test目錄) touch a.md (新建a.md文件)


這裏提醒下:在進行任何 Git 操作之前,都要先切換到 Git 倉庫目錄,也就是先要先切換到項目的文件夾目錄下。


這個時候我們先隨便操作一個命令,比如 git status ,可以看到如下提示(別糾結顏色之類的,配置與主題不一樣而已):






意思就是當前目錄還不是一個 Git 倉庫。


git init


這個時候用到了第一個命令,代表初始化 git 倉庫,輸入 git init 之後會提示:






可以看到初始化成了,至此 test 目錄已經是一個 git 倉庫了。


git status


緊接着我們輸入 git status 命令,會有如下提示:






默認就直接在 master 分支,關於分支的概念後面會提,這時最主要的是提示 a.md 文件 Untracked files ,就是說 a.md 這個文件還沒有被跟蹤,還沒有提交在 git 倉庫裏呢,而且提示你可以使用 git add 去操作你想要提交的文件。


git status 這個命令顧名思義就是查看狀態,這個命令可以算是使用最頻繁的一個命令了,建議大家沒事就輸入下這個命令,來查看你當前 git 倉庫的一些狀態。


git add


上面提示 a.md 文件還沒有提交到 git 倉庫裏,這個時候我們可以隨便編輯下 a.md 文件,然後輸入 git add a.md ,然後再輸入 git status :






此時提示以下文件 Changes to be committed , 意思就是 a.md 文件等待被提交,當然你可以使用 git rm –cached 這個命令去移除這個緩存。


git commit


接着我們輸入 git commit -m ‘first commit’ ,這個命令什麼意思呢? commit 是提交的意思,-m 代表是提交信息,執行了以上命令代表我們已經正式進行了第一次提交。


這個時候再輸入 git status ,會提示 nothing to commit。


git log


這個時候我們輸入 git log 命令,會看到如下:






git log 命令可以查看所有產生的 commit 記錄,所以可以看到已經產生了一條 commit 記錄,而提交時候的附帶信息叫 ‘first commit’ 。


git add & git commit


看到這裏估計很多人會有疑問,我想要提交直接進行 commit 不就行了麼,爲什麼先要再 add 一次呢?首先 git add 是先把改動添加到一個「暫存區」,你可以理解成是一個緩存區域,臨時保存你的改動,而 git commit 纔是最後真正的提交。這樣做的好處就是防止誤提交,當然也有辦法把這兩步合併成一步,不過後面再介紹,建議新手先按部就班的一步步來。


git branch


branch 即分支的意思,分支的概念很重要,尤其是團隊協作的時候,假設兩個人都在做同一個項目,這個時候分支就是保證兩人能協同合作的最大利器了。舉個例子,A, B倆人都在做同一個項目,但是不同的模塊,這個時候A新建了一個分支叫a, B新建了一個分支叫b,這樣A、B做的所有代碼改動都各自在各自的分支,互不影響,等到倆人都把各自的模塊都做完了,最後再統一把分支合併起來。


執行 git init 初始化git倉庫之後會默認生成一個主分支 master ,也是你所在的默認分支,也基本是實際開發正式環境下的分支,一般情況下 master 分支不會輕易直接在上面操作的,你們可以輸入 git branch 查看下當前分支情況:






如果我們想在此基礎上新建一個分支呢,很簡單,執行 git branch a 就新建了一個名字叫 a 的分支,這時候分支 a 跟分支 master 是一模一樣的內容,我們再輸入 git branch 查看的當前分支情況:






但是可以看到 master 分支前有個 * 號,即雖然新建了一個 a 的分支,但是當前所在的分支還是在 master 上,如果我們想在 a 分支上進行開發,首先要先切換到 a 分支上纔行,所以下一步要切換分支


git checkout a


執行這個命令,然後再輸入 git branch 查看下分支情況:






可以看到當前我們在的分支已經是a了,這個時候 A 同學就可以盡情的在他新建的a分支去進行代碼改動了。


那有人就說了,我要先新建再切換,未免有點麻煩,有沒有一步到位的,聰明:


git checkout -b a


這個命令的意思就是新建一個a分支,並且自動切換到a分支。


git merge


A同學在a分支代碼寫的不亦樂乎,終於他的功能完工了,並且測試也都ok了,準備要上線了,這個時候就需要把他的代碼合併到主分支master上來,然後發佈。git merge 就是合併分支用到的命令,針對這個情況,需要先做兩步,第一步是切換到 master 分支,如果你已經在了就不用切換了,第二步執行 git merge a ,意思就是把a分支的代碼合併過來,不出意外,這個時候a分支的代碼就順利合併到 master 分支來了。爲什麼說不出意外呢?因爲這個時候可能會有衝突而合併失敗,留個包袱,這個到後面進階的時候再講。


git branch -d


有新建分支,那肯定有刪除分支,假如這個分支新建錯了,或者a分支的代碼已經順利合併到 master 分支來了,那麼a分支沒用了,需要刪除,這個時候執行 git branch -d a 就可以把a分支刪除了。


git branch -D


有些時候可能會刪除失敗,比如如果a分支的代碼還沒有合併到master,你執行 git branch -d a 是刪除不了的,它會智能的提示你a分支還有未合併的代碼,但是如果你非要刪除,那就執行 git branch -D a 就可以強制刪除a分支。


git tag


我們在客戶端開發的時候經常有版本的概念,比如v1.0、v1.1之類的,不同的版本肯定對應不同的代碼,所以我一般要給我們的代碼加上標籤,這樣假設v1.1版本出了一個新bug,但是又不曉得v1.0是不是有這個bug,有了標籤就可以順利切換到v1.0的代碼,重新打個包測試了。


所以如果想要新建一個標籤很簡單,比如 git tag v1.0 就代表我在當前代碼狀態下新建了一個v1.0的標籤,輸入 git tag 可以查看歷史 tag 記錄。






可以看到我新建了兩個標籤 v1.0、v1.1。


想要切換到某個tag怎麼辦?也很簡單,執行 git checkout v1.0 ,這樣就順利的切換到 v1.0 tag的代碼狀態了。


OK,以上全是一些最基本的Git操作,而且全是在本地環境進行操作的,完全沒有涉及到遠程倉庫,下一章節將以遠程 GitHub 倉庫爲例,講解下本地如何跟遠程倉庫一起同步協作,另外今天講的全是最基礎最簡單的Git操作,一步步來,後續再繼續講解一下Git的高階以及一些Git的酷炫操作。


另外,考慮到可能會有人嫌我講解的太基礎太慢,畢竟我是針對小白,所以得一步步來,迫不及待的想要提前自己學習的不妨在我公衆號 AndroidDeveloper 回覆「git」關鍵字,獲取一份我推薦的還不錯的 Git 學習資料,不謝,畢竟我這麼帥!


1. SSH


你擁有了一個 GitHub 賬號之後,就可以自由的 clone 或者下載其他項目,也可以創建自己的項目,但是你沒法提交代碼。仔細想想也知道,肯定不可能隨意就能提交代碼的,如果隨意可以提交代碼,那麼 GitHub 上的項目豈不亂了套了,所以提交代碼之前一定是需要某種授權的,而 GitHub 上一般都是基於 SSH 授權的。


那麼什麼是 SSH 呢? 簡單點說,SSH是一種網絡協議,用於計算機之間的加密登錄。目前是每一臺 Linux 電腦的標準配置。而大多數 Git 服務器都會選擇使用 SSH 公鑰來進行授權,所以想要在 GitHub 提交代碼的第一步就是要先添加 SSH key 配置。


2. 生成SSH key


Linux 與 Mac 都是默認安裝了 SSH ,而 Windows 系統安裝了 Git Bash 應該也是帶了 SSH 的。大家可以在終端(win下在 Git Bash 裏)輸入 ssh 如果出現以下提示證明你本機已經安裝 SSH, 否則請搜索自行安裝下。






緊接着輸入 ssh-keygen -t rsa ,什麼意思呢?就是指定 rsa 算法生成密鑰,接着連續三個回車鍵(不需要輸入密碼),然後就會生成兩個文件 id_rsa 和 id_rsa.pub ,而 id_rsa 是密鑰,id_rsa.pub 就是公鑰。這兩文件默認分別在如下目錄裏生成:


Linux/Mac 系統 在 ~/.ssh 下,win系統在 /c/Documents and Settings/username/.ssh 下,都是隱藏文件,相信你們有辦法查看的。


接下來要做的是把 id_rsa.pub 的內容添加到 GitHub 上,這樣你本地的 id_rsa 密鑰跟 GitHub 上的 id_rsa.pub 公鑰進行配對,授權成功纔可以提交代碼。


3. GitHub 上添加 SSH key


第一步先在 GitHub 上的設置頁面,點擊最左側 SSH and GPG keys :






然後點擊右上角的 New SSH key 按鈕:






需要做的只是在 Key 那欄把 id_rsa.pub 公鑰文件裏的內容複製粘貼進去就可以了(上述示例爲了安全粘貼的公鑰是無效的),Title 那欄不需要填寫,點擊 Add SSH key 按鈕就ok了。


這裏提醒下,怎麼查看 id_rsa.pub 文件的內容?


Linux/Mac 用戶執行以下命令:


cd ~/.ssh
cat id_rsa.pub
Windows用戶,設置顯示隱藏文件,可以使用 EditPlus 或者 Sublime 打開復制就行了。


SSH key 添加成功之後,輸入 ssh -T [email protected] 進行測試,如果出現以下提示證明添加成功了。






4. Push & Pull


在提交代碼之前我們先要了解兩個命令,也是上次的文章沒有介紹的,因爲這兩個命令需要跟遠程倉庫配合。


Push :直譯過來就是「推」的意思,什麼意思呢?如果你本地代碼有更新了,那麼就需要把本地代碼推到遠程倉庫,這樣本地倉庫跟遠程倉庫就可以保持同步了。


代碼示例: git push origin master


意思就是把本地代碼推到遠程 master 分支。


Pull:直譯過來就是「拉」的意思,如果別人提交代碼到遠程倉庫,這個時候你需要把遠程倉庫的最新代碼拉下來,然後保證兩端代碼的同步。


代碼示例: git pull origin master


意思就是把遠程最新的代碼更新到本地。一般我們在 push 之前都會先 pull ,這樣不容易衝突。


5. 提交代碼


添加 SSH key 成功之後,我們就有權限向 GitHub 上我們自己的項目提交代碼了,而提交代碼有兩種方法:


Clone自己的項目 我們以我在 GitHub 上創建的 test 項目爲例,執行如下命令:


git clone [email protected]:stormzhang/test.git
這樣就把 test 項目 clone 到了本地,你可以把 clone 命令理解爲高級點的複製,這個時候該項目本身就已經是一個git 倉庫了,不需要執行 git init 進行初始化,而且甚至都已經關聯好了遠程倉庫,我們只需要在這個 test 目錄下任意修改或者添加文件,然後進行 commit ,之後就可以執行:


git push origin master
進行代碼提交,這種是最簡單方便的一種方式。


至於怎麼獲取項目的倉庫地址呢?如下圖:






關聯本地已有項目 如果我們本地已經有一個完整的 git 倉庫,並且已經進行了很多次 commit ,這個時候第一種方法就不適合了。


假設我們本地有個 test2 的項目,我們需要的是在 GitHub 上建一個 test 的項目,然後把本地 test2 上的所有代碼 commit 記錄提交到 GitHub 上的 test 項目。


第一步就是在 GitHub 上建一個 test 項目,這個想必大家都會了,就不用多講了。


第二步把本地 test2 項目與 GitHub 上的 test 項目進行關聯,切換到 test2 目錄,執行如下命令:


git remote add origin [email protected]:stormzhang/test.git
什麼意思呢?就是添加一個遠程倉庫,他的地址是 [email protected]:stormzhang/test.git ,而 origin 是給這個項目的遠程倉庫起的名字,是的,名字你可以隨便取,只不過大家公認的只有一個遠程倉庫時名字就是 origin ,爲什麼要給遠程倉庫取名字?因爲我們可能一個項目有多個遠程倉庫?比如 GitHub 一個,比如公司一個,這樣的話提交到不同的遠程倉庫就需要指定不同的倉庫名字了。


查看我們當前項目有哪些遠程倉庫可以執行如下命令:


git remote -v
接下來,我們本地的倉庫就可以向遠程倉庫進行代碼提交了:


git push origin master
就是默認向 GitHub 上的 test 目錄提交了代碼,而這個代碼是在 master 分支。當然你可以提交到指定的分支,這個之後的文章再詳細講解。


對了,友情提醒,在提交代碼之前先要設置下自己的用戶名與郵箱,這些信息會出現在所有的 commit 記錄裏,執行以下代碼就可以設置:


git config —global user.name "stormzhang"
git config —global user.email "[email protected]"


1. 用戶名和郵箱


我們知道我們進行的每一次commit都會產生一條log,這條log標記了提交人的姓名與郵箱,以便其他人方便的查看與聯繫提交人,所以我們在進行提交代碼的第一步就是要設置自己的用戶名與郵箱。執行以下代碼:


git config --global user.name "stormzhang"
git config --global user.email "[email protected]"
以上進行了全局配置,當然有些時候我們的某一個項目想要用特定的郵箱,這個時候只需切換到你的項目,以上代碼把 –global 參數去除,再重新執行一遍就ok了。


PS:我們在 GitHub 的每次提交理論上都會在 主頁的下面產生一條綠色小方塊的記錄,如果你確認你提交了,但是沒有綠色方塊顯示,那肯定是你提交代碼配置的郵箱跟你 GitHub 上的郵箱不一致,GitHub 上的郵箱可以到 Setting -> Emails裏查看。


2. alias


我們知道我們執行的一些Git命令其實操作很頻繁的類似有:


git commit
git checkout
git branch
git status
...
這些操作非常頻繁,每次都要輸入完全是不是有點麻煩,有沒有一種簡單的縮寫輸入呢?比如我對應的直接輸入以下:


git c
git co
git br
git s
...
是不是很簡單快捷啊?這個時候就用到了alias配置了,翻譯過來就是別名的意思,輸入以下命令就可以直接滿足了以上的需求。


git config --global alias.co checkout  # 別名
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.br branch
當然以上別名不是固定的,你完全可以根據自己的習慣去定製,除此之外還可以設置組合,比如:


git config --global alias.psm 'push origin master'
git config --global alias.plm 'pull origin master'
之後經常用到的git push origin master 和 git pull origin master 直接就用 git psm 和 git plm 代替了,是不是很方便?


另外這裏給大家推薦一個很強大的 alias 命令,我們知道我們輸入 git log 查看日誌的時候是類似這樣的:






告訴大家一個比較屌的命令,輸入**git log –graph –pretty=format:’%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset’ –abbrev-commit –date=relative ** 然後日誌這樣了:






是不是比較清晰,整個分支的走向也很明確,但是每次都要輸這麼一大串是不是也很煩?這時候你就該想到 alias 啊:


git config --global alias.lg "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative"
這樣以後直接輸入 git lg 就行了。


3. 其他配置


當然還有一些其他有用的配置,默認情況下 git 用的編輯器是 vi ,如果不喜歡可以改成其他編輯器,比如我習慣 vim 。


git config --global core.editor "vim"  # 設置Editor使用vim
你們如果喜歡其他編輯器可自行搜索配置,前提是本機有安裝。


有些人納悶我的終端怎麼有各種顏色,自己卻不是這樣的,那是因爲你們沒有開啓給 Git 着色,輸入如下命令即可:


git config --global color.ui true
還有些其他的配置如:


git config --global core.quotepath false # 設置顯示中文文件名
以上基本所有的配置就差不多了,默認這些配置都在 ~/.gitconfig 文件下的,你可以找到這個文件查看自己的配置,也可以輸入 git config -l 命令查看。


4. diff


diff命令算是很常用的,使用場景是我們經常在做代碼改動,但是有的時候2天前的代碼了,做了哪些改動都忘記了,在提交之前需要確認下,這個時候就可以用diff來查看你到底做了哪些改動,舉個例子,比如我有一個 a.md 的文件,我現在做了一些改動,然後輸入 git diff 就會看到如下:






紅色的部分前面有個 - 代表我刪除的,綠色的部分前面有個 + 代表我增加的,所以從這裏你們很一目瞭然的知道我到底對這個文件做了哪些改動。


值得一提的是直接輸入 git diff 只能比較當前文件和暫存區文件差異,什麼是暫存區?就是你還沒有執行 git add 的文件。


當然跟暫存區做比較之外,他還可以有其他用法,如比較兩次 commit 之間的差異,比較兩個分支之間的差異,比較暫存區和版本庫之間的差異等,具體用法如下:


git diff <$id1> <$id2>   # 比較兩次提交之間的差異
git diff <branch1>..<branch2> # 在兩個分支之間比較 
git diff --staged   # 比較暫存區和版本庫差異
5. checkout


我們知道 checkout 一般用作切換分支使用,比如切換到 develop 分支,可以執行:


git checkout develop
但是 checkout 不只用作切換分支,他可以用來切換tag,切換到某次commit,如:


git checkout v1.0
git checkout ffd9f2dd68f1eb21d36cee50dbdd504e95d9c8f7 # 後面的一長串是commit_id,是每次commit的SHA1值,可以根據 git log 看到。
除了有“切換”的意思,checkout 還有一個撤銷的作用,舉個例子,假設我們在一個分支開發一個小功能,剛寫完一半,這時候需求變了,而且是大變化,之前寫的代碼完全用不了了,好在你剛寫,甚至都沒有 git add 進暫存區,這個時候很簡單的一個操作就直接把原文件還原:


git checkout a.md
這裏稍微提下,checkout 命令只能撤銷還沒有 add 進暫存區的文件。


6. stash


設想一個場景,假設我們正在一個新的分支做新的功能,這個時候突然有一個緊急的bug需要修復,而且修復完之後需要立即發佈。當然你說我先把剛寫的一點代碼進行提交不就行了麼?這樣理論上當然是ok的,但是這會產品垃圾commit,原則上我們每次的commit都要有實際的意義,你的代碼只是剛寫了一半,還沒有什麼實際的意義是不建議就這樣commit的,那麼有沒有一種比較好的辦法,可以讓我暫時切到別的分支,修復完bug再切回來,而且代碼也能保留的呢?


這個時候 stash 命令就大有用處了,前提是我們的代碼沒有進行 commit ,哪怕你執行了 add 也沒關係,我們先執行


git stash
命令,什麼意思呢?意思就是把當前分支所有沒有 commit 的代碼先暫存起來,這個時候你再執行 git status 你會發現當前分支很乾淨,幾乎看不到任何改動,你的代碼改動也看不見了,但其實是暫存起來了。執行


git stash list
你會發現此時暫存區已經有了一條記錄。


這個時候你可以切換會其他分支,趕緊把bug修復好,然後發佈。之後一切都解決了,你再切換回來繼續做你之前沒做完的功能,但是之前的代碼怎麼還原呢?


git stash apply
你會發現你之前的代碼全部又回來了,就好像一切都沒發生過一樣,緊接着你最好需要把暫存區的這次 stash 記錄刪除,執行:


git stash drop
就把最近一條的 stash 記錄刪除了,是不是很方便?其實還有更方便的,你可以使用:


git stash pop
來代替 apply 命令,pop 跟 apply 的唯一區別就是 pop 不但會幫你把代碼還原,還自動幫你把這條 stash 記錄刪除,省的自己再 drop 一次了,爲了驗證你可以緊接着執行 git stash list 命令來確認是不是已經沒有記錄了。


最後還有一個命令介紹下:


git stash clear
就是清空所有暫存區的記錄,drop 是隻刪除一條,當然後面可以跟 stash_id 參數來刪除指定的某條記錄,不跟參數就是刪除最近的,而 clear 是清空。


7. merge & rebase


我們知道 merge 分支是合併的意思,我們在一個 featureA 分支開發完了一個功能,這個時候需要合併到主分支 master 上去,我們只需要進行如下操作:


git checkout master
git merge featureA
其實 rebase 命令也是合併的意思,上面的需求我們一樣可以如下操作:


git checkout master
git rebase featureA
rebase 跟 merge 的區別你們可以理解成有兩個書架,你需要把兩個書架的書整理到一起去,第一種做法是 merge ,比較粗魯暴力,就直接騰出一塊地方把另一個書架的書全部放進去,雖然暴力,但是這種做法你可以知道哪些書是來自另一個書架的;第二種做法就是 rebase ,他會把兩個書架的書先進行比較,按照購書的時間來給他重新排序,然後重新放置好,這樣做的好處就是合併之後的書架看起來很有邏輯,但是你很難清晰的知道哪些書來自哪個書架的。


只能說各有好處的,不同的團隊根據不同的需要以及不同的習慣來選擇就好。


8. 解決衝突


假設這樣一個場景,A和B兩位同學各自開了兩個分支來開發不同的功能,大部分情況下都會盡量互不干擾的,但是有一個需求A需要改動一個基礎庫中的一個類的方法,不巧B這個時候由於業務需要也改動了基礎庫的這個方法,因爲這種情況比較特殊,A和B都認爲不會對地方造成影響,等兩人各自把功能做完了,需要合併的到主分支 master 的時候,我們假設先合併A的分支,這個時候沒問題的,之後再繼續合併B的分支,這個時候想想也知道就有衝突了,因爲A和B兩個人同時更改了同一個地方,Git 本身他沒法判斷你們兩個誰更改的對,但是這個時候他會智能的提示有 conflicts ,需要手動解決這個衝突之後再重新進行一次 commit 提交。我隨便在項目搞了一個衝突做下示例:






以上截圖裏就是衝突的示例,衝突的地方由 ==== 分出了上下兩個部分,上部分一個叫 HEAD 的字樣代表是我當前所在分支的代碼,下半部分是一個叫 baidu_activity 分支的代碼,可以看到 HEAD 對 gradle 插件進行了升級,同時新增了一個插件,所以我們很容易判斷哪些代碼該保留,哪些代碼該刪除,我們只需要移除掉那些老舊代碼,而且同時也要把那些 «< HEAD、==== 以及 »»»baidu_activity 這些標記符號也一併刪除,最後進行一次 commit 就ok了。


我們在開發的過程中一般都會約定儘量大家寫的代碼不要彼此影響,以減少出現衝突的可能,但是衝突總歸無法避免的,我們需要了解並掌握解決衝突的方法。


==============================================================
生成多個公鑰私鑰的方法。
$ ssh-keygen -t rsa -C "[email protected]"  
下面就繼續輸入你公私鑰的地址, 命名規則   要 在後面加  _rsa     不然會有亂碼。
 /c/Users/MYPC/.ssh/myabc_rsa

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章