使用IDEA學習廖雪峰官方Git教程


如果你只是想在開發過程中使用Git,而不是成為一個Git的專業研究者,那么非常推薦你看廖雪峰的官方網站的Git教程。廖老師在他的這個系列教程中的一句話我非常喜歡。

“本教程只會讓你成為Git用戶,不會讓你成為Git專家。很多Git命令只有那些專家才明白(事實上我也不明白,因為我不是Git專家),但我保證這些命令可能你一輩子都不會用到。既然Git是一個工具,就沒必要把時間浪費在那些“高級”但幾乎永遠不會用到的命令上。一旦你真的非用不可了,到時候再自行Google或者請教專家也未遲。”

而現如今,強如idea的編輯器早就將Git的操作圖形化,操作起來不要太絲滑,就和使用一款新插件一樣。所以我在這里重申廖雪峰老師的話——本教程只會讓你成為Git的圖形化工具用戶,我保證大部分情況你都可以不使用Git指令。

哈哈哈,開玩笑的啦,還是強烈建議大家通讀廖雪峰老師的教程,做到知其然,知其所以然。

本系列文章將展示如何使用idea的圖形化界面操作Git,內容、案例均來自廖雪峰的官方網站的Git教程

Git簡介

Git的特點和發家史,很有意思,詳見廖老師的文章。這里筆者就簡單介紹一下Git的原理,知道這些會讓你更好的閱讀本教程。請看圖:

其中Workspace就是工作區,當多人共同完成一個項目,廖老師每個人的電腦都是一個工作區。在工作區里,你可以修改代碼。
Index/Stage就是暫存區,他和工作區是孿生兄弟,每個工作區都有一個暫存區。未完成的修改的代碼都可以存入暫存區。
Repository就是倉庫區(或本地倉庫),可以理解為不是暫存區的存儲區,一般完成的功能的代碼才會存放在這里。
Remote就是遠程倉庫,所有的人都公用一個遠程倉庫,不在本機。

我們工作的順序是先和遠程倉庫建立聯系,然后克隆(clone)一份代碼到自己的電腦的本地倉庫,然后建立一個工作區,開始工作,修改代碼。完成一個小功能后,加入(add)暫存區,當整個功能都完成的時候,提交(commit)到本地倉庫。等待其他同伴開發完成他們的功能,推送(push)到遠程倉庫。

安裝Git

可以閱讀筆者的Git安裝教程。不過別忘了,下載以后還需要配置git.exe。

創建版本庫

初始化一個Git的版本庫操作如下,會彈出一個瀏覽文件的對話框,選擇需要的目錄即可。但是在實際開發中幾乎不需要這樣的操作。

所以筆者在這里調換了一下廖老師教程的循序,第一步,咱們直接連接遠程倉庫。

遠程倉庫

在操作之前你需要完成以下內容

  1. 安裝Git並配置;
  2. 申請一個GitHub賬號,Gitee和GitLab都是一個道理;
  3. 在idea上登錄GitHub

添加遠程倉庫(remote)

方法一

廖老師的方法太麻煩了,idea直接一步到位。

第一步:創建好你的項目后,如下圖點擊。

第二步:填寫彈出分享項目到GitHub的窗口。

Repository name就是倉庫名。Remote就是遠程倉庫名。origin這是Git默認的叫法,也可以改成別的,但是origin這個名字一看就知道是遠程庫。Description就是項目描述。private是設置是否私有,私有庫別人看不見。

第三步:單機Share,會自動進行一個add+commit的操作。就是將創建的代碼添加到自動創建的本地倉庫(不要在意內容,筆者使用的不是空項目)。

這個對話框的意思就是以后會自動add所有新添加的文件到暫存區。打上不再提醒的對勾,點擊Add就大功告成了。

創建完成之后,來到GitHub主頁,就可以找到自己的庫了。

這樣做的好處就是——你可以在本地進行適當的開發,例如環境的配置和項目的初始化,之后再上傳Git。而不是連接一個空的遠程庫,在搭建一個SpringBoot環境。

但是同樣有弊端,快捷方式只能分享到GitHub,其他的遠程倉庫暫不支持,像有的公司在自己的Git庫上面開發,自然使用不了。

方法二

所以廖老師的方法也介紹給大家,必須要先創建遠程庫,獲得這個遠程庫的地址,如下圖:

核心就在VCS->Git->Remotes,如下圖:

然后在Remotes界面輸入遠程庫地址,進行連接。

如果本地和遠程都有文件,想讓兩者建立關聯,如何操作。首先選擇本地分支,update一下,會提示沒有相關聯的遠程分支,需要選擇一個分支。之后會處理兩個分支的沖突,然后就建立了關聯。具體如下圖

克隆(clone)項目

知道如何自己創建項目了,我們還需要了解如何獲取別人的項目。

第一步:
先找到需要克隆的項目的鏈接,如圖所示

第二步:導入
File -> new -> Project from Version Control

版本控制選擇git,URL框輸入git聯接,編輯本地的存儲位置,單擊clone即可。

廖老師還給我們介紹了https和ssh的區別。

你也許還注意到,GitHub給出的地址不止一個,還可以用https://github.com/michaelliao/gitskills.git這樣的地址。實際上,Git支持多種協議,默認的git://使用ssh,但也可以使用https等其他協議。
使用https除了速度慢以外,還有個最大的麻煩是每次推送都必須輸入口令,但是在某些只開放http端口的公司內部就無法使用ssh協議而只能用https。

刪除遠程倉庫

刪除遠程倉庫的操作必須在GitHub上面進行,方法如下:
打開項目->Setting->Options->(拉到最下面找到)Delete this repository,彈出以下界面,重新輸入一下項目名。

還需要輸入GitHub密碼,就可以刪除了。如果是想讓本地和遠程庫失去連接,在remote界面,點這個小減號就行。

時光穿梭機(add+commit)

將一個文件創建並存放到Git的本地倉庫的動作叫做提交(commit)。其分為三步,第一步自然是創建文件,第二步是將文件添加(add)到暫存區,然后再commit到本地倉庫。

第一步:創建文件,自動add

首先我們新建一個文件readme.txt,由於之前的設置,idea會自動add所有的新建文件,所以在使用idea的過程中我們完全不需要add。

如果需要手動add,也非常簡單,使用如下圖操作即可。

第二步:commit

點擊編輯器右上角的綠色小對勾(也可能在左上角)。

彈出的對話框就是使用git status指令查看是否有內容被修改的可視化界面,如下(vcs.xml是idea的初始化文件,請無視)

雙擊你想看的文件,就可以知道有哪些修改了。這和git diff是一樣的

同時提示一下大家,無論是文件還是代碼,紅色代表沒有進行add,綠色代表and但未commit,藍色代表已經commit且有改動,灰色代表已經刪除的但未commit。

在紅框中填寫提交的信息wrote a readme file,然后我們點擊圖片上的Commit按鈕,即可完成提交。這完全可以理解為Git指令 git commit -m "wrote a readme file"

提交完成后按圖示方法即可查看日志。相當於git log

版本回退(reset+revert)

我們用這個的方法在上一個案例的基礎上再提交兩次。最后的內容應該如下:

版本1:wrote a readme file

Git is a version control system.
Git is free software.

版本2:add distributed

Git is a distributed version control system.
Git is free software.

版本3:append GPL

Git is a distributed version control system.
Git is free software distributed under the GPL.

就有了如下的Git日志

如何做到版本回退呢,廖老師使用了git reset指令。如果使用idea,可以按照下圖的提示點擊。

會彈出下面的提示框。

簡單翻譯一下:
這會重設當前分支的head到選擇的commit,並且更新工作樹和暫存空間依照選擇的模式

  • 軟:文件不會更改,不同會被儲存
  • 混合:文件不會更改,不同不會被儲存
  • 硬:文件會被轉換到被選擇的提交的狀態,提示:任何修改都會丟失
  • 保持:文件會被轉換到被選擇的提交的狀態,但是本地的修改會被完整保存

具體的效果大家可以嘗試一下,觀察一下效果。就如提示的內容一樣,這樣的操作會丟失數據,雖然可以像廖老師所說,通過git reflog查看提交的id,再reset回去。因為目前我們還是在本地單機操作Git,在多人共同編碼的時候,這樣的回退不僅容易刪除別人的代碼,而非常容易操作混亂,造成了很多不必要的麻煩。所以在實際開發中,如果我們需要回退某個提交,我們會使用到revert

按照下圖的提示點擊,注意選擇名字為append GPL的commit,如果選擇其他commit會有融合沖突,這個我們以后再說。

點擊之后,會發現文件退回的同時,彈出一個commit的對話框,如下:

這就是 reset 和 revert 的區別。reset只不過是向后移動了Head指針,如下圖:

而 revert 是回滾一個commit,再把這個回滾commit,如下圖:

總結一下:

  1. reset 是刪除某個commit,期間所有commit都會被回滾;revert 是回滾某個commit,只回滾一個commit,並且生成一個新的commit;
  2. reset 時HEAD是向后移動了;revert 只不過是反向提交,它的HEAD是一直向前的;
  3. reset 會造成大量的沖突,所以適合在本地開發同時沒有push到遠端的時候使用;而revert造成的沖突非常有限,適合在push到遠端的代碼進行回滾。

最后還介紹一種回滾,就是undo。

如果你查看源代碼,會發現undo就是reset soft

但是idea對它進行了一定的限制和提示,它只能作用於最后一個commit,把這個commit從工作樹刪除,並且保留修改,同時建立一個New Changlist。效果如下:

這個名為append GPL的New Changlist可以將改動的文件分門別類的放置在不同的文件夾中,等全部修改完畢后一起提交,一般在分模塊開發時會使用。也就是在開發完一個完整的模塊時,將這個模塊上改動的代碼設置到一個文件夾中,然后再一起提交。

撤銷修改

想要撤銷修改需要考慮以下四種情況

  1. 沒有add(idea的自動add只能add新創建的內容,修改過后的內容會在commit的時候自動add)
  2. 已經add但是未commit

按照如下圖所示的操作,即可達到git reset HEAD <file>git checkout -- file的操作。讓未commit的修改全部消失。

由於idea的特殊機制,我們還可以有一種操作。

按照下圖指示,依次點擊左邊框的綠色條狀長條,回滾箭頭,即可撤銷修改。這和git checkout -- file非常類似,但是實現原理不同,git checkout -- file是使用暫存區的文件替換原有文件,而idea使用的是編譯器自身的功能,類似ctrl+z

消失的內容可以按照下圖指示進行查詢。

  1. 已經commit但是未push

可以使用上文介紹的reset和revert回滾。如果已經add但是未commit的內容非常多,也可以先commit,然后再使用reset和revert回滾。

  1. 已經push到遠程倉庫

同樣可以使用reset和revert回滾,只不過需要commit+push的操作才能通過修改的方式來實現撤銷。

刪除文件

如果你使用Git指令,那么你需要像添加操作一樣,先手動刪除文件,然后使用指令git rm test.txt,將刪除操作加載到暫存庫,然后再commit到本地倉庫。

如果使用idea的圖形化版本控制插件,直接刪就行,下次commit會把刪除的動作也提交上去。

灰色的文件就是刪除的內容

分支管理

分支的概念請大家從廖雪峰老師的教程里面學習。

創建與合並分支

master就是默認的主分支,創建分支非常簡單,只需要按照下圖提示點擊,彈出對話框輸入名字即可。

idea在創建完分支后會自動切換,也就是git checkout -b dev指令的效果。

如何查找自己所在的分支?非常簡單,在編輯器的右下角可以查看。等於git branch的效果

融合分支(merge)也非常簡單,首先我們切換到主分支,操作如下:

然后我們選擇要合並的分支點擊merge into current。

融合完成后,還是在同一個菜單,點擊delete即可刪除分支。

解決沖突(merge)

創建一個新的分支,和master分支分別commit不同的內容。具體如下:

feature1分支

Git is a distributed version control system.
Git is free software distributed under the GPL.
Creating a new branch is quick AND simple.

master分支

Git is a distributed version control system.
Git is free software distributed under the GPL.
Creating a new branch is quick & simple.

可以看出兩個版本有一個不同就是&和AND,如果merge,會發生什么?會彈出一個沖突的界面。

在這個界面中有很多快捷按鈕,但都不是我們介紹的重點,我們需要雙擊readme.txt來查看沖突並解決它,雙擊結果如下:

我們可以清晰地看出界面分為左中右三個板塊,分別是當前分支master、合並后的結果和需要合並的分支feature。同時上方有很多便捷操作的按鈕,具體功能大家可以嘗試一下,非常簡單。我們合並的主要操作就是三個板塊相連的間隔中的X>>來實現,X就是放棄修改,>>就是選擇修改。同時三個板塊都是可以編輯的文件,也就是說在合並過程中你都是可以增加代碼和注釋的。在這里我們需要放棄&,然后保留AND,合成完成的結果如下:

合並完成我們再看Git log,會發現一個分支創建又合並的過程,應該很好理解。是不是非常方便。

分支管理策略

關於Fast forward模式,廖老師這么說。

通常,合並分支時,如果可能,Git會用Fast forward模式,但這種模式下,刪除分支后,會丟掉分支信息。
如果要強制禁用Fast forward模式,Git就會在merge時生成一個新的commit,這樣,從分支歷史上就可以看出分支信息。

在idea中多分支都有修改的情況下,會默認禁用Fast forward模式的,這樣你就會看到合並后的Merge branch 'feature1'的commit。

再如分支策略,廖老師講的非常簡單明了,其實這就是Git Flow,是一種對Git操作的約束,用來讓大型項目顯得僅僅有條。如果想了解,可以閱讀 【一篇文章就夠了】淺談GitFlow

Bug 分支(stash+cherry-pick)

教程中有這么一個場景:

當你接到一個修復一個代號101的bug的任務時,很自然地,你想創建一個分支issue-101來修復它,但是,等等,當前正在dev上進行的工作還沒有提交。並不是你不想提交,而是工作只進行到一半,還沒法提交,預計完成還需1天時間。但是,必須在兩個小時內修復該bug,怎么辦?

解決方法,就是使用stash,很簡單的道理,就是隱藏未提交的代碼,並保持。

如圖所示,可以看出有兩個修改,一個是添加了新的文件file.txt,第二個是加了一行代碼。而我們的bug就是comment和author的內容寫錯了。按照圖示進行點擊,即可實現git stash指令的效果。

少頃,修改的代碼就會消失,如下圖。這時我們就可以切換分支修改bug了,注意當前分支如果有未提交的代碼是不能切換分支的會導致代碼丟失。

教程中新建立了一個issue-101分支然后修改過后再合並到master,我們就直接在master上面修改即可。

又有一個新的場景。

在master分支上修復了bug后,我們要想一想,dev分支是早期從master分支分出來的,所以,這個bug其實在當前dev分支上也存在。
那怎么在dev分支上修復同樣的bug?重復操作一次,提交不就行了?
有木有更簡單的方法?
有!

答案就是cherry-pick命令。如圖所示即可實現對單個commit的同步操作。

我們再點擊Stash Changes...同一菜單的unStash Changes...來查看stash 列表,效果等同於git stash list

View:查看隱藏的代碼
Drop:刪除選中隱藏
Clear:清空所有隱藏
Apply Stash:將隱藏代碼恢復

Pop stash:Apply的同時會Drop隱藏

點擊Apply Stash就能讓隱藏的代碼恢復。注意Stash過后的分支如果你又有新的改動一定要commit,如果不commit,當你使用Apply Stash重新獲取代碼的時候就會失敗,也有可能因為操作不當導致代碼消失。如果有了新的commit,在apply stash時就會當成融合沖突處理。就比如我們現在,因為我們融合了master上面修改的代碼,所以現在的代碼和stash時的代碼不一樣了,就需要處理一下。方法就和之前的merge一樣。

然后就發現代碼又回來了,如果這里file.txt沒有出現,請刷新一下文件。

feature分支

idea的刪除操作如果不成功會再使用強制刪除指令進行刪除。

同時還會給出一些提示,沒有融合的提交會被丟棄。然后你可以Restore撤回,View Commit查看提交。

如果已經推到遠程倉庫的分支,刪除之后會彈出提示框,單機Delete Tracked Branch,即可刪除遠程倉庫的分支

如果錯過彈窗,可以直接刪除。

git指令如下:

多人協作(pull+push)

廖老師教程中的很多操作都被idea一鍵化了。我們先新建一個文件夾再次拉取代碼,這就是為什么之前說電腦中的一個目錄代表一個工作區,如果你換個目錄就可以模擬兩人同時修改代碼的操作。

推送和拉取在idea中形象的被兩個簡單所表示,藍色的向下的時拉取,綠色的向上的時推送。idea中拉取是update project。git fetch是抓取遠程倉庫修改的內容,抓取到后不會改變本地倉庫,只有git merge的時候才會改變。而git pull就是fetch+merge的組合,和update project效果一樣。

推送就是git push,一模一樣。這里push還有一個小技巧,就是在commit的時候可以直接使用push,省去了多一步的操作。

如何拉取遠程倉庫分支,如下:

效果就是創建一個本地分支,再和遠程倉庫進行連接,等同於checkout -b dev origin/dev

多人操作的情況下,你的每次改動都需要考慮到別人的代碼是否也發生了改動,所有在每次push的時候idea都會主動申請一次pull操作,如果有沖突,先處理沖突在push,沒有就直接push。

rebase

什么是變基(rebase)?可以參考以下的文章:https://blog.csdn.net/SafeVidulInfo/article/details/113808961。但是在實際開發中很少使用到變基,因為有一定的危險性,所有使用者尤其是新手一定要慎用。具體如何操作,見下文。

情況一:當合並別人的提交時

當多人提交時,我們必須要先融合別人的代碼,所以必定會形成下圖這種分叉然后再回歸的情況。

而我們使用變基(rebase)就可以避免這一情況。在update project的時候選擇下面的選項。

就可以了。

情況二:當合並不同分支時

操作如下:

但是一定要注意,這個和merge的不同,merge是將選擇的分支合並到當前分支,而rebase是將當前分支變基到選擇的分支。也就是說為了達到合並feature1代碼的效果,如果我們使用merge,我們應該切換到dev,然后選擇feature1進行merge操作。如果我們使用rebase,我們應該切換到feature1,然后選擇dev進行rebase操作。

標簽管理

所有的Tag操作應該都在這里了。

Push Tag的操作在push commit的操作窗口的右下角。

刪除已經提交的Tag需要再刪除遠程倉庫的Tag,單機提示框的delete on Remote即可

其他

之后的使用GitHub、Gitee、配置別名什么的,就沒啥可以講的了,感興趣的可以看看。
忽略特殊文件,可以從GitHub項目:gitignore中直接復制。選擇Global>JetBrains.gitignore + Java.gitignore 基本上就可以滿足了。
SourceTree的話,可以參考 SourceTree的使用介紹。但是筆者還是更喜歡Idea的,不需要再下載一個軟件。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM