git使用之idea篇

尛騩發表於2020-10-19

1. 前言

公司內編寫程式碼肯定會用到版本控制工具,現在比較流行的就是git和svn,本菜鳥也是在某公司實習了有一陣子了,還沒實習之前也只是瞭解過git,到了實習才有了實操,現在抽空系統地整理一下在idea上怎麼使用git。

2. 從遠端倉庫拉取程式碼

  1. 先獲取git專案的url,先從別人的倉庫把git專案拉到自己的倉庫,然後在自己的倉庫裡找到git專案的url
  2. 在idea上方選單欄選擇File--New--Project from Version Control--Git。如果當前idea還沒開啟任何專案,停留在選擇專案的視窗上,則點選Check out from Version Control--Git
  3. 在彈出來的框框中,填寫入我們git專案的url,如果還沒有登入賬號的話記得先登入一下,Test成功之後點選Clone即成功拉取git專案至本地

3. 拉取、建立、切換分支

建立分支在idea的右下角那裡有Git:master,點選它即可以拉取、建立、切換分支,結構如下

拉取分支

選擇一個Remote Branches(遠端倉庫分支),點選Checkout As,之後輸入分支名稱,即可將遠端倉庫的分支拉取到本地倉庫,即LocalBranches下,注意拉取的分支是與遠端分支相連結的,你在該本地分支做了任何改動,push上去的話就是推到你當時拉取的遠端分支,在本地分支的右邊也會顯示該分支對應的遠端分支,即當push程式碼時,是會更新對應的遠端分支

建立分支

上一點說了拉取分支,拉取後我們的改動都會影響遠端分支,如果我們想不影響到那條遠端分支的話,我們就需要建立一個新的分支,建立分支很簡單,只需要點選+New Branch,輸入分支名稱,即可建立新的分支並自動切換到新分支下,此時該分支也只是在本地倉庫建立了(所以在該分支的右側是不會看到說與遠端倉庫哪條分支相連結,即右側那裡為空白),當你做了一次push操作後,便能在遠端倉庫上看到一條新的分支,在這裡我們建立一條branch1分支,做為建立分支的示例,也做為下一步提交程式碼的分支

切換分支

切換分支就是Checkout,我們從遠端倉庫Checkout As拉取分支到本地後,就可以直接使用Checkout進行分支的切換

4.程式碼提交

我們使用git最主要的需求之一就是提交程式碼到伺服器上,主要使用commit和push,commit能把我們的程式碼提交到本地倉庫裡,push則將我們commit的程式碼再提交到遠端倉庫上。

若當前專案是git專案的時候,我們可以在idea的右上角那裡,看到一個藍色的箭頭和一個綠色的勾,分別是pull和commit不是commit和push,指令在idea的位置如下

  • idea右上角藍色箭頭:pull
  • idea右上角綠色小勾:commit
  • ctrl shift k/右鍵專案–Git–Repository–Push:push

程式碼提交注意點

  1. commit程式碼後,記得先pull一下遠端程式碼,因為有可能你commit的程式碼,別人也對那部分程式碼進行了改動、或者建立了位置檔名都相同的檔案,這時候idea就會提示我們進行程式碼合併,下面我們來場景復現一次,在復現場景之前我們先做一些準備工作:拉取同一個git專案放到新的路徑下、進行一次簡單的提交讓新專案也能看到branch1分支,後面才進行場景復現
  • 自己一個人復現多人commit衝突的話,我們就只能再拉取一次專案,然後再修改一下git專案的本地路徑即可

  • 為了確保我們另一個新拉取的專案也能看到我們的branch1分支,我們先進行一次簡單的commit,push
  • 建立一個ClassOne的java類,建立類的時候它會彈窗讓你選擇是否add檔案,只有add了的檔案,我們在commit的時候才會儲存到我們的倉庫,提示如下

  • 點選idea右上角的綠色小勾commit,在下面的文字框可以輸入內容,能夠表明我們這次commit的目的,雖然我們不寫message也能commit成功,但寫上message肯定是一個好習慣,方便其他同事理解,記錄你的工作內容,方便後期回憶程式碼內容等等;上面列出的檔案就是指我們本次commit程式碼的所有改動,新增、刪除、修改檔案都能在這裡進行檢視

  • ctrl shift k把我們的commit給push到遠端倉庫上,在push的視窗上我們能看到我們這次push裡有多少次commit,也能看到是從哪個本地倉庫分支提交到哪個遠端倉庫分支,點選push之後即可將程式碼推到我們的遠端倉庫

  • 之後我們來到我們剛剛新拉下來的新的git專案,點選pull–OK,即可以更新我們的程式碼,就能看到我們前面建立的branch1分支以及新建立的ClassOne類,然後我們就拉取並切換到branch1分支
  • 前面準備了這麼多,現在我們已經有兩個相同的git專案,這裡先定義好兩個專案就分別叫A和B吧,方便後面進行表述
  • 在A的branch1分支上的ClassOne類裡,我們新增一條簡單的列印程式碼,之後commit、push
public static void main(String[] args) {
    System.out.println("print by A");
}
  • 我們再來到B的branch1分支的ClassOne類裡,我們也新增一條列印程式碼,這個時候我們可以看到,AB都在ClassOne類上同一個地方做了修改,這時候我們commit,pull,則會出現程式碼衝突,彈出如下視窗
public static void main(String[] args) {
    System.out.println("print by B");
}

  • 彈出上面這個視窗說明我們的程式碼跟別人的程式碼起了衝突了,我們需要進行合併解決衝突,才能在B的branch1分支順利提交程式碼,我們選中衝突的檔案,點選merge,來到如下視窗,選擇要保留和刪除的程式碼,再點選apply即可完成pull,之後我們就能正常commit啦,(右鍵程式碼行數那裡–Annotate即可顯示修改過對應部分程式碼的使用者,在工作中我們也會通過這個找到改了程式碼人的進行溝通決定最終保留什麼)不過其實如果我們沒有進行pull這一操作直接push,idea也會自動幫我們去檢查程式碼是否有衝突,有的話也會讓我們處理衝突,但是commit後pull一下再push肯定是一個好習慣

  1. 提交程式碼第二個注意點:若要pull程式碼,記得先commit一下你的程式碼,否則可能會丟失你的程式碼!!!,這個是偶爾會偶爾不會,不容易復現,記住pull前最好能就commit一下程式碼,不過若真的造成程式碼丟失,可以右鍵專案–LocalHistory–Show History,檢視歷史程式碼改動,當時不弄丟程式碼就不會有那麼多事了哈哈哈哈,或者通過下方工具欄的version control裡的log也能進行一定的恢復

5. Cherry-Pick指令(內含undo commit,revert commit簡單介紹)

Cherry-Pick能夠將單次commit在當前分支上進行一次commit,下面進行一次簡單的使用

  • 切換到master分支(切換分支後在沒有改程式碼前pull一下最新程式碼也是個好習慣),然後我們在idea下方工具欄的version control的log找到我們Create ClassOne的那個commit,右鍵–Cherry-Pick
  • 點選了Cherry-Pick後我們就能直接來到commit的視窗,idea會將那次commit的程式碼改動和commit message一起復制過來(當然若有衝突也是需要先進行處理),其實跟正常的commit沒有太大的區別
  • 這時候可能有小夥伴就要想了,我們上面的操作是cherry pick一個正常的建立類的commit,如果我的cherry pick一個修改程式碼的類(像上面的在ClassOne加上列印語句的那個commit),而此時我們並沒有這個類,會是個什麼情況
  • 在復現上面要求的情景,我們先把我們第一次cherry pick過來的commit給撤銷掉,可用undo commit/revert commit,下面簡單介紹一下
  • undo commit:右鍵version control下的log的最新一條commit記錄,即我們的第一次cherry pick記錄,點undo commit–OK(點選undo commit後在change list中就能看到這條記錄,點選undo commit的時候會有彈窗,一般直接點ok即可,這個彈窗可以簡單地規劃一下這個撤銷在change list怎麼顯示,小功能小夥伴們可以自行研究一下),即可撤銷commit,在log下面commit記錄也會消失,但因為我們cherry pick而新建的ClassOne類卻不會消失,我們可以再點選commit進行提交
  • revert commit:同樣右鍵commit記錄,點revert commit,它會再次進行一次commit,不過這次commit是你右鍵的那條commit的反轉,這個應該很好理解,像這裡我們第一次commit是建立一個ClassOne類,那revert commit就是進行一次刪除ClassOne類的Commit
  • 總結undo commit與revert commit,undo commit就是把commit記錄給消除掉,不過改動還是會保留在當前專案,你可以再次進行commit每次undo commit也只能是undo最新一條記錄,至於為什麼大家意會一下也都能懂吧;revert commit是再提交一次上一次commit的反轉,因此它是最終會產生兩條commit記錄
  • 上面如果你是選擇了undo commit的話,記得正式把ClassOne刪除了(可手動刪,也可到version control–Local Changes–右鍵記錄–revert),我們講完了撤銷commit,再回到正題,cherry pick一個修改程式碼的類,可是我們當前分支連這個類都沒有,是個什麼情況
  • 我們直接cherry pick新增一條列印語句的一個commit,就能發現起了衝突,需要我們進行解決,就能正常commit了

6. rebase指令

rebase指令能讓我們將多次commit選擇性地合併成一次commit

  • 設想有一個場景,我們在這個分支commit了6次程式碼,可是我們只需要其中的第1、3、5次commit,2、4、6次的commit不要了
  • 這個時候按照前面所學的,我們可以一次一次地單獨點選2、4、6的commit進行revert commit,(這裡再說明一下undo commit是不可行的,因為undo commit每次只能undo最上面的一個commit記錄),這樣revert commit之後,我們就有了總共9次的commit記錄(6個原本的commit,3個revert commit),完成了只保留3個commit的內容
  • 使用rebase來解決這個問題,我們可以先將commit2、4、6進行合併,合併完之後再進行一次revert commit,下面給個commit的記錄,看文字應該就能知道大概幹了啥,不多解釋

  • 右鍵commit1–Interactively Rebase from Here,然後會來到一個視窗,按照如下填寫,其中action挑幾個做下簡單介紹
    • skip就是跳過,不做合併,並且該commit會消失,如果沒了這個commit會影響後面的commit,它會讓你merge程式碼的;
    • pick就是把它們合併到這個commit裡
    • squash就是表示壓縮,壓縮了它就會跑到上面最近的pick
  • 右上角的箭頭可以調整commit的順序,因此說rebase是可選擇性地合併,你可以選擇跳過、改變commit的順序

  • 按照如上圖填寫之後就點選Start Rebasing,開始合併commit,上面的操作就是(這裡需要小夥伴們注意一下順序):第一個commit就是我們的create class的操作,第二個commit就是我們edit class的操作,點選Start Rebasing後會彈出兩次視窗,讓我們填寫commit message,因為我們上面是有兩個pick,自然就是兩個commit,commit message自己記得填寫規範,我這裡是隨便的一次截圖,大家不要學壞的

  • 最後的結果就能變成將原本的6個commit變成2個commit,下面的commit for create class就是我們原本的1、3、5次commit,commit for edit class就是我們原本的2、4、6次commit

  • 回到我們一開始的題目,要求是隻保留第1、3、5次commit,去除2、4、6次commit,這裡我們就直接對我們的commit for edit class來一次undo或者revert即可,用revert個人覺得會更好一點,因為至少有一條log,萬一以後又反悔又要把commit加回來呢,直接undo的話你的這些edit就直接銷聲匿跡了

7. merge指令

merge能讓我們把一個分支的程式碼合併到另一個分支,以下圖為例,我們當時在master分支,我們選擇branch1分支–Merge into Current,就能把branch1分支的commit直接都merge來到master分支,當然有衝突就得先解決衝突啦

merge完之後,在log下面是沒有看到什麼新的記錄的,當你commit的時候,就能看到那些源分支的commit都已經也都commit到當前分支下了

  • merge的話,它會將所有的commit都merge來到當前分支下,若只想要部分commit,可以使用rebase,之後進行一次cherry-pick,當然如果commit比較少的話一個一個地cherry-pick也是可以的

8. rollback指令

rollback能讓我們把程式碼回滾到某一個指定的位置,我們這裡選擇一下create class那個位置,點reset Current Branch to Here…

點了之後彈出一個視窗,我也看不懂啥玩意,直接選預設的就可以了

點選之後雖然程式碼還沒有變化,但前面那些commit都已經undo了,真要撤銷我們只需要在change list那裡revert一下即可

9. tag指令

tag就是標籤的意思,我們可以指定某一條commit記錄,右鍵–New Tag…,之後填寫tag名字,即可成功標記,操作簡單截圖我就偷個懶不載啦,比如我們弄了一個tag1

標記完了之後,來到idea右下角選擇切換分支的那裡,現在要說回我們一開始的那個沒說到的地方,Checkout Tag or Revision…,點選它之後會讓我們填寫一個tag名或一個分支名,可以看到它會根據我們輸入有一些下拉結果給我們選,可以說是十分貼心

選擇我們的tag1後我們就能成功來到我們標記了tag的地方,idea右下角看分支名是一個奇怪的編號,我這裡是Git:efa3c640,這個應該是隨機生成的編號,它不是一個分支

後面隨便進行一點改動我們commit一下試試,它給了一個警告,大概意思就是提醒你要儲存好你跳轉到這個tag之前的程式碼

commit我們倒是能正常commit,但是想直接push就不行了,因為我們現在還沒有弄一隻分支去容納它,我們建立一隻新分支後,就能成功push啦

10. 寫在最後

git應該也算是講得七七八八了吧,上面的如果能搞懂的話是應該可以滿足工作中對git的需要的,其實其中的部分指令像rebase、tag這些用到的還是比較少,也可能是我太菜了輪不到我來用哈哈哈哈,以後如果還有啥想補充的再來吧。

相關文章