軟件工程 實驗一 Git版本管理


 

實驗目的:

1)了解分布式分布式版本控制系統的核心機理;

2)   熟練掌握git的基本指令和分支管理指令;

實驗內容:

1)安裝git

2)初始配置git ,git init git status指令

3)掌握git log ,git add ,git diff 指令

4) 掌握git tag git branch,git commit 指令

5)掌握git revert 指令

實驗記錄:

1)實驗內容以及結果的截圖:

2)實驗過程中發生的問題與解決。

4.1.4 從頭創建倉庫

  在進行 Git 倉庫的創建之前我們首先需要進行的就是項目目錄的創建,

創建項目目錄

  在我的F盤下創建一個叫做 se2020-git-course 的目錄,在該目錄中再創建另一個叫做 new-git-project 的目錄並使用 cd 命令移到 new-git-project 目錄下。代碼如下圖:

創建倉庫

  在對 Git 倉庫進行 commit 或執行任何其他操作之前都需要一個實際存在的倉庫。要使用 Git 新建一個倉庫,我們將使用 git init 命令來完成倉庫的創建。代碼如下圖:

克隆現有倉庫

  首先需要驗證終端所在的位置。在克隆任何內容之前都需要確保命令行工具已定位於正確的目錄下。克隆項目會新建一個目錄,並將克隆的 Git 倉庫放在其中。問題是無法創建嵌套的 Git 倉庫。因此,確保終端的當前工作目錄沒有位於 Git 倉庫中。在 Git 上進行克隆的方法是調用我們將在終端上運行的命令 git clone,然后傳入要克隆的 Git 倉庫的路徑(通常是 URL)。代碼及運行結果如下圖:

查看克隆后倉庫的狀態

  git status 是了解 Git 的核心所在。它將告訴我們 Git 正在考慮什么,以及 Git 所看到的我們倉庫的狀態因此可利用 git status 命令來隨時查看當前倉庫的狀態。代碼及運行結果如下圖:

*git statu命令拓展

  git status 命令將顯示很多信息,具體取決於你的文件狀態、工作目錄和倉庫。但是你不需要過於關心這些內容…只需運行 git status,它將顯示你需要知道的信息。

輸出結果告訴了我們幾條信息:

  • On branch master – 這部分告訴我們 Git 位於 master 分支上,(也就是默認分支)。

  • Your branch is up-to-date with 'origin/master'. – 因為我們使用 git clone 從另一台計算機上復制了此倉庫,因此這部分告訴我們項目是否與所復制的倉庫保持同步狀態。我們不會在其他計算機上處理該項目,因此這一行可以忽略。

  • nothing to commit, working directory clean – 表示沒有任何待定的更改。

  可以將這一輸出結果看作“休息狀態(resting state)”。代碼及運行結果如下圖:

  上圖是在已經具有 commit 的倉庫中運行 git status 之后的狀態。我們切換到一個空目錄中運行 git status 命令。在結果中出現清晰明了的 "No commits yet"(尚未有任何提交)。代碼及運行結果如下圖:

4.1.5 git log

git log命令

   git log 命令用於顯示倉庫中所有 commit 的信息。默認情況下該命令會顯示倉庫中每個 commit 的:SHA、作者、日期、消息等。代碼及運行結果如圖:

git log --oneline命令

  我們可以使用 git log --oneline 命令以不同的格式風格來代替 git log 的輸出,相比較而言 git log --oneline的輸出結果更為簡短並且可以節省大量空間。

  git log --oneline命令的顯示格式通常為:

  • 每行顯示一個 commit

  • 顯示 commit 的 SHA 的前 7 個字符

  • 顯示 commit 的消息

·  git log --oneline 命令的代碼及運行結果如下圖:

git log --stat命令

   git log --stat命令可以用來顯示 commit 中更改的文件以及添加或刪除的行數。(stat 是“統計信息 statistics”的簡稱)

   git log --stat命令的顯示格式通常為:

  • 顯示被修改的文件

  • 顯示添加/刪除的行數

  • 顯示一個摘要,其中包含修改/刪除的總文件數和總行數

  git log --stat 命令的代碼及運行結果如下圖:

查看更改 

git log -p 命令

  git log -p 命令是一個可用來顯示對文件作出實際更改的命令。( -p 是 --patch 的簡寫)。

  git log -p 命令通常會向默認的輸出中添加以下信息:

  • 顯示被修改的文件

  • 顯示添加/刪除的行所在的位置

  • 顯示做出的實際更改

  代碼及運行結果如下圖:

git show 命令

  通過以上的各個命令的實驗過程會發現,上面的命令在執行結束之后需要在補丁(修改)輸出中不斷向下滾動,以便找到正確的 commit 並查看其信息。能夠顯示特定 commit 的詳情,而不用關心倉庫中的所有其他內容。git show 命令通常將 SHA 作為最后一個參數提供給命令。(例如:git log -p fdf5493)git show 命令的輸出和 git log -p 命令的完全一樣。因此默認情況下,git show 也會顯示:commit、作者、日期、commit 消息、補丁信息。代碼及運行結果如下圖:

 4.1.6 git add& git commit&git diff

准備工作

  首先在new-git-project目錄下創建一個叫做 index.html 的文件,並添加一些起始代碼之后分別建立 js 和css 文件夾,並在文件下分別建立 app.js 和 app.css 文件,文件內容可為空。准備工作完成之后利用 git status 命令查看長褲狀態。代碼及運行結果如下圖:

git add 命令

   若想要將文件提交到倉庫中,首先需要將這些文件從工作目錄移到暫存區。可以利用 git add 命令來完成相關操作。在終端上運行 git add 命令將 index.html 添加到暫存區中,代碼及運行結果如下圖:

  與添加index.html相同,我們將目錄下的其他文件利用 git add 命令也一同放入到暫存區中。完成之后利用 git status 命令查看當前倉庫狀態。代碼及運行結果如下圖:

git commit 命令

  使用 git commit 命令將暫存區中的文件進行提交。代碼及運行結果如下圖:

   完成代碼的提交之后利用 git status 命令再次查看倉庫狀態。代碼及運行結果如下圖:

 使用 -m 選項繞過編輯器

  先使用 git add 命令將文件移到暫存區,並使用 git status 驗證文件是否位於暫存區,使用 git commit 命令提交 commit,並添加提交說明 Add header to blog。代碼及運行結果如下圖:

   使用 git log 命令和 git log --stas 命令檢查剛剛提交的 commit。代碼及運行結果如下圖:

 git diff

  通過使用 git status 命令我們可以知道哪些文件被更改了可是不會顯示到底是什么樣的更改,像這種情況我們通常可以使用 git diff 命令。git diff 命令用來查看那些已被加入但是尚未提交的更改。該命令的顯示格式通常為:

  • 已經修改的文件

  • 添加/刪除的行所在的位置

  • 執行的實際更改

  代碼及運行結果如下圖:

 git ignore 命令

  在我們的項目目錄中如果有其他文件並且我們並不想將其提交到倉庫中這是如果再使用 git add .命令來添加所有文件就會非常不方便。遇到這種想將某個文件保留在項目的目錄結構中並且確保它不會意外地提交到項目當中,可以使用名稱特殊的文件 .gitignore (文件名開頭的點,很重要!)。我們將希望忽略的文件(例如:project.docx)寫出到  .gitignore 中。當面對許多文件需要忽略的情況時可以另外使用通配符來配合完成。通俗的說,git ignore 命令的功能就是告訴 git 不應跟蹤哪些文件。代碼及運行結果如下圖:

4.1.7 標簽、分支

git  tag命令(標簽)

  git tag 命令用來標記特定的 commit ,在添加新的 commit 時標簽不會移動。下面我們從宏觀層面了解下 git 標簽在倉庫中的作用。首先查看項目使用 git log 的效果,代碼及運行結果如下圖:

  注意上圖所顯示的結果(只需注意 SHA 和 commit 消息)我們將使用 git tag 命令與倉庫的標簽進行交互。在終端輸入:git tag -a v1.0。該條命令將打開代碼編輯器,並等待用戶為標簽輸入信息。我們輸入"Ready for content"作為tag。代碼及運行結果如下圖:

 *上面采用的命令帶有 -a 打開編輯器為一個帶注釋的標簽。我們也可以不適用 -a 此時它將創建一個輕量級的標簽。建議使用前者即帶注釋的標簽。

  驗證標簽:保存並退出編輯器后,終端界面上什么也不會顯示。我們只需要往項目中輸入 git tag 命令就可以知道我們添加了的所有標簽。代碼及運行結果如下圖:

   查看標簽:使用 git log 命令查看標簽位於倉庫的哪個位置。下圖中的輸出結果顯示的 tag: v1.0 這就是標簽!標簽與 commit 相綁定。因此,該標簽與 commit 的 SHA 位於同一行。代碼及運行結果如下圖:

  刪除標簽:如果我們將標簽消息中的某個字打錯了或標簽名稱打錯了(輸入 v0.1,而不是 v1.0)最簡單的方法是刪除這個標簽並重新創建。可以通過輸入 git tag -d 命令來刪除 這個錯誤的標簽名(例如:git tag -d v1.0)。代碼及運行結果如下圖:

 *向以前的 commit 中添加標簽:git tag -a 命令給一般直接向最近的 commit 添加標簽,但如果用戶提供了 SHA,命令則向具體的 commit 添加標簽。以 SHA 為 574dff7 為例,代碼及運行結果如下圖:

 git branch標簽(分支)

   git 中的分支非常靈活,能夠實現一些很強大的功能。而git branch 命令則是用來與 git 的分支進行交互的。通常包括:列出倉庫中的所有分支名稱、創建新的分支、刪除分支。如果我們只輸入 git branch 命令,終端將列出倉庫中的所有分支。代碼及運行結果如下圖:

   創建分支:我們只需要使用 git branch 命令並提供要創建分支對應的名稱。但是同時需要注意的是新創建的分支它不是當前系統分支。提示符顯示的才是當前分支master。要使用新創建的 sidebar 分支,我們需要使用 git checkout 命令手動的切換到該分支。以創建 sidebar 的分支為例,代碼及運行結果 如下圖:

*對於 git checkout 命令請務必了解該命令的工作方式。運行該命令執行時首先:從工作目錄中刪除 git 跟蹤的所有文件和目錄(git 跟蹤的文件存儲在倉庫中,因此什么也不會丟失)。之后:再轉到倉庫中並提取分支指向的 commit 所對應的所有文件和目錄。由於命令的執行方式,因此此命令將刪除 master 分支中的 commit 引用的所有文件,它會將這些文件替換為 sidebar 分支中的 commit 引用的文件。

  仔細的觀察可以發現當執行完 git checkout 命令之后提示符會開始顯示 sidebar。我們可以使用 git log --oneline 命令來清晰的觀察提示符中的有關分支的有用信息。特殊指示符"HEAD"具有一個指向 sidebar 分支的箭頭。它指向 sidebar 是因為 sidebar 分支是當前分支,現在提交的任何 commit 將添加到 sidebar 分支。代碼及運行結果 如下圖:

   活躍分支:提示符通常顯示活躍分支。但這是我們對提示符進行的特殊自定義,如果你使用的是不同的計算機,我們可以通過最快速的 git branch 命令的方式來判斷活躍分支。(活躍分支名稱旁邊會顯示一個星號)代碼及運行結果如下圖:

   刪除分支:如果我們不再需要某個分支時我們可以使用 git branch -d 命令來完成。但時 git 中對分支的刪除有很嚴格的限制,只有滿足了這些限制刪除操作才能完成。如果某個

  • 將要刪除的分支上有任何其他分支上都沒有包含的 commit(也就是這個 commit 是將要被刪除的分支所獨有的),git 不會刪除該分支。
  • 如果我們創建了 sidebar 分支並向其添加了 commit 然后嘗試使用 git branch -d 命令刪除該分支。git 不會讓你刪除該分支,因為我們無法刪除當前所在的分支。
  • 如果我們切換到 master 分支並嘗試刪除 sidebar 分支,git 也不會讓你刪除,因為 sidebar 分支上的新 commit 會丟失!如果要強制刪除則需要使用大寫的 -D ,即 git branch -D 。代碼及運行結果如下圖:

 高效分支

  基礎操作:我們首先需要在當前目錄的基礎上進行四步操作,分別為:刪除 前面建好的 siderbar 分支、所有文件暫存並提交到倉庫、切換到master分支、運行git status, 確認出現  working tree clean 或 working directory clearn。代碼及運行結果如下圖:

   分支實戰:通過上面的基礎操作之后,現在我們的左右代碼都位於 master 分支上了。現在我們使用分支來完成一下各項更改:

  • 在 master 分支上向頁面添加默認顏色:首先想 css 文件夾下的 app.css 文件中加入設置背景色的代碼然后保存文件並將該文件添加到暫存區再將其 commit 到倉庫。 commit 的內容寫為:Set background color for page ,最后通過git log --oneline 命令來檢查 commit 記錄。代碼及運行結果如下圖:

  • 創建一個 sidebar 分支為頁面創建側欄:假定我們並不確定是否喜歡新的背景色。因此我們要將 sidebar 分支放在設置頁面顏色的 commit 之前。以確保我們更容易的更改操作。根據上圖中 git log --oneline 命令執行的結果來看,我們將 sidebar 分支設置哎 SHA 為 574dff7 上(即運行 git branch sidebar 574dff7)。之后運行 git checkout 命令切換到新的 sidebar 分支上再運行 git log --oneline。代碼及運行結果如下圖:

  • 在 master 分支上更改頁面的標題:我們將 <aside> 內容添加到 <main> 元素旁邊,作為 <div class = "container"> 元素的子級。在 <aside> 標簽中添加 This a message ! 所有操作完畢之后我們可以 commit 任何更改。代碼及運行結果如下圖:

  *特別提醒:千萬不要更改 CSS 文件。否則會出現“合並沖突”(merge conflict)。

  • 在 master 分支上更改頁面的標題:使用 git branch master 命令切換到 master 分支上。需要特別注意的是,由於所有代碼都妥善地保存在 sidebar 分支上故當切換到 master 分支時新的側欄的相關 HTML 已經不在了!我們將 index.html 中的<H>標題從之前的"Expedition"改為"Adventure"。保存 index.html 文件並進行 commit 以將此更改添加到倉庫中(將 commit 消息設為"Improve site heading for SEO"),提交用git log --oneline 命令檢查倉庫。代碼及運行結果如下圖:

  •  同時查看所有分支:到目前為止我們已經在三個不同的分支上進行了多項更改。我們知道可以使用 git log 命令來查看分支的各種信息但是去只能局限於當前的分支。這里我們可以使用 git log 的幾個新的選項。--graph 選項將條目和行添加到輸出的最左側,顯示了實際的分支。--all選項會顯示倉庫中的所有分支。

    運行此命令將顯示倉庫中的所有分支和 commit。代碼及運行結果如下圖:

合並

  當你在主題分支上做出更改后,如果覺得不想要該分支上的更改,則可以刪掉該分支,或者你決定要保留更改,則可以將該分支上的更改與其他分支上的更改進行合並。git 可以自動將不同分支上的更改合並到一起。這種分支和合並功能正是 git 的強大之處!你可以在分支上做出小的或大的更改,然后使用 git 合並這些更改。發生合並時,git 將:查看將合並的分支、查看分支的歷史記錄並尋找兩個分支的 commit 歷史記錄中都有的單個 commit、將單個分支上更改的代碼行合並到一起、提交一個 commit 來記錄合並操作。代碼及運行結果如下圖:

commit 合並沖突

  大部分情況下,git 將能夠成功地合並分支。但是,有時候 git 無法完全自動地進行合並。合並失敗時,就稱為合並沖突。大部分情況下,git 將能夠成功地合並分支。但是,有時候 git 無法完全自動地進行合並。合並失敗時,就稱為合並沖突。代碼及運行結果如下圖:

合並沖突小結

  當相同的行在要合並的不同分支上做出了更改時,就會出現合並沖突。git 將在合並途中暫停,並告訴你存在沖突,以及哪些文件存在沖突。要解決文件中的沖突需要:找到並刪掉存在合並沖突指示符的所有行、決定保留哪些行、保存文件、暫存文件、提交 commit。代碼及運行結果如下圖:

*解決合並沖突

  git 使用合並沖突指示符來告訴我們兩個不同分支上的哪些行導致了合並沖突,以及原始行是什么。要想解決合並沖突,我們需要:選擇保留哪些行以及刪掉所有帶指示符的行。

git commit --amend命令

  上面的合並沖突中通過將標題設為Advanture Quest解決了該沖突。現在可以通過 git commit --amensd 命令將標題更改為 Quests & Crusades來解決沖突。代碼及運行結果如下圖:

 

 git revert 命令

  當我們創建了一個包含一些更改的 commit,我們可以使用 git revert 命令來還原它。代碼及運行結果如下圖:

 

 相關 commit 引用

  我們可以使用 SHA、標簽、分支和特殊的 SEAD 指針引用 commit。有時候這些並不足夠,你可能需要引用相對於另一個 commit 的 commit。我們可以使用特殊的“祖先引用”字符來告訴 git 這些相對引用。這些字符為:^ 表示 父commit 、~ 表示第一個父 commit。兩者區別主要體現在通過合並而創建的 commit 中。合並 commit 具有兩個父級。對於合並 commit,^ 引用用來表示第一個父 commit,而 ^2 表示第二個父 commit。第一個父 commit 是當你運行 git merge 時所處的分支,而第二個父 commit 是被合並的分支。一下是我自己運行 git log --oneline --graph --all 命令的結果:

git reset 命令

  我們通常使用 git reset 命令用來重置(清除)commit。主要包括:將 HEAD 和當前分支指針移到目標 commit、清除 commit、將 commit 的更改移到暫存區、取消暫存 commit 的更改。git 根據所使用選項來判斷是清除、暫存之前 commit 的更改,還是取消暫存之前 commit 的更改。這些選項包括:使用 --hard 選項清除 commit、使用 --soft 選項將 commit 的更改移至暫存區、使用 --mixed選項取消暫存已被 commit 的更改。

  git reset -mixed 命令執行后結果如下圖:

備份分支

  注意,使用git reset 命令將清除當前分支上的 commit。因此,如果你想跟着操作接下來出現的所有重置操作,需要在當前 commit 上創建一個分支,以便用作備份。

在進行任何重置操作之前,我通常會在最近的 commit 上創建一個 backup 分支,因此如果出現錯誤,我可以返回這些 commit。

實驗總結與體會:

  整個實驗圍繞 gIt 的各種命令的實際應用背景展開,通過在一個個實例中去深刻理解命令的用途及含義。這種需求推動知識的學習方法讓我在解決一個又一個實際問題中既獲得了成就感也學會了各種命令。但是這次的實驗是驗證型實驗整體沒有太高的難度但是需要花一定的時間去完成每一個分模塊,特別是當自己運行的結果與自己預期的不同時需要花費大量的時間去查找錯誤原因。所以從整個實驗過程來看,雖然實驗結束了但是各種知識點也僅僅的有所了解,只有通過課后的進一步鞏固強化才能更好的吸收和消化實驗的真個內容。

思考題:

  Q:總結分布式版本控制系統的核心機理

  分布式版本控制系統是一種有效、高速地處理從很小到非常大的項目版本管理系統。與它相對的是集中式版本控制系統。在分布式版本控制系統中客戶端並不像集中式版本控制系統那樣提取最新版本的文件快照,而是把代碼倉庫完整地鏡像下來。這樣的核心機理就輕松的解決了集中式版本控制系統中容易出現的也是很致命的中央服務器單點故障。分布式版本控制系統沒有所謂的"中央服務器",每個人的電腦上都是一個完整的版本庫。通常分布式版本控制系統有一台"偽中央服務器",但是這個服務器的作用僅僅是用來方便"交換"大家的修改,沒有它大家仍然可以正常工作。


免責聲明!

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



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