<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                幾乎所有的版本控制系統都以某種形式支持分支。 使用分支意味著你可以把你的工作從開發主線上分離開來,以免影響開發主線。 在很多版本控制系統中,這是一個略微低效的過程——常常需要完全創建一個源代碼目錄的副本。對于大項目來說,這樣的過程會耗費很多時間。 有人把 Git 的分支模型稱為它的‘必殺技特性’,也正因為這一特性,使得 Git 從眾多版本控制系統中脫穎而出。 為何 Git 的分支模型如此出眾呢? Git 處理分支的方式可謂是難以置信的輕量,創建新分支這一操作幾乎能在瞬間完成,并且在不同分支之間的切換操作也是一樣便捷。 與許多其它版本控制系統不同,Git 鼓勵在工作流程中頻繁地使用分支與合并,哪怕一天之內進行許多次。 理解和精通這一特性,你便會意識到 Git 是如此的強大而又獨特,并且從此真正改變你的開發方式。 ## 分支簡介 為了真正理解 Git 處理分支的方式,我們需要回顧一下 Git 是如何保存數據的。 或許你還記得 起步 的內容,Git 保存的不是文件的變化或者差異,而是一系列不同時刻的文件快照。 在進行提交操作時,Git 會保存一個提交對象(commit object)。知道了 Git 保存數據的方式,我們可以很自然的想到——該提交對象會包含一個指向暫存內容快照的指針。 但不僅僅是這樣,該提交對象還包含了作者的姓名和郵箱、提交時輸入的信息以及指向它的父對象的指針。首次提交產生的提交對象沒有父對象,普通提交操作產生的提交對象有一個父對象,而由多個分支合并產生的提交對象有多個父對象, 為了更加形象地說明,我們假設現在有一個工作目錄,里面包含了三個將要被暫存和提交的文件。 暫存操作會為每一個文件計算校驗和(使用我們在 起步 中提到的 SHA-1 哈希算法),然后會把當前版本的文件快照保存到 Git 倉庫中(Git 使用 blob 對象來保存它們),最終將校驗和加入到暫存區域等待提交: ~~~ $ git add README test.rb LICENSE $ git commit -m 'The initial commit of my project' ~~~ 當使用 git commit 進行提交操作時,Git 會先計算每一個子目錄(本例中只有項目根目錄)的校驗和,然后在 Git 倉庫中這些校驗和保存為樹對象。 隨后,Git 便會創建一個提交對象,它除了包含上面提到的那些信息外,還包含指向這個樹對象(項目根目錄)的指針。如此一來,Git 就可以在需要的時候重現此次保存的快照。 現在,Git 倉庫中有五個對象:三個 blob 對象(保存著文件快照)、一個樹對象(記錄著目錄結構和 blob 對象索引)以及一個提交對象(包含著指向前述樹對象的指針和所有提交信息)。 ![Figure 9. 首次提交對象及其樹結構](https://box.kancloud.cn/f1a5dcd2022c283338b4a6a6cc0bd086_800x443.png) 做些修改后再次提交,那么這次產生的提交對象會包含一個指向上次提交對象(父對象)的指針。 ![Figure 10. 提交對象及其父對象](https://box.kancloud.cn/a93852af1809af57921fd829948192f6_800x265.png) Git 的分支,其實本質上僅僅是指向提交對象的可變指針。 Git 的默認分支名字是 master。 在多次提交操作之后,你其實已經有一個指向最后那個提交對象的 master 分支。 它會在每次的提交操作中自動向前移動。 >Note Git 的 “master” 分支并不是一個特殊分支。 它就跟其它分支完全沒有區別。 之所以幾乎每一個倉庫都有 master 分支,是因為 git init 命令默認創建它,并且大多數人都懶得去改動它。 * * * * * ![Figure 11. 分支及其提交歷史](https://box.kancloud.cn/e4677e6c70a1c7b2aafb10bf4b7e3d1d_800x430.png) ## 分支創建 Git 是怎么創建新分支的呢? 很簡單,它只是為你創建了一個可以移動的新的指針。 比如,創建一個 testing 分支, 你需要使用 git branch 命令: `$ git branch testing` 這會在當前所在的提交對象上創建一個指針。 ![Figure 12. 兩個指向相同提交歷史的分支](https://box.kancloud.cn/08d777aeface2958e043e4dc60121687_800x331.png) 那么,Git 又是怎么知道當前在哪一個分支上呢? 也很簡單,它有一個名為 HEAD 的特殊指針。 請注意它和許多其它版本控制系統(如 Subversion 或 CVS)里的 HEAD 概念完全不同。 在 Git 中,它是一個指針,指向當前所在的本地分支(譯注:將 HEAD 想象為當前分支的別名)。 在本例中,你仍然在 master 分支上。 因為 git branch 命令僅僅 創建 一個新分支,并不會自動切換到新分支中去。 ![Figure 13. HEAD 指向當前所在的分支](https://box.kancloud.cn/3997e9f656dd3d00c46aedb6d3663b9d_800x467.png) 你可以簡單地使用 git log 命令查看各個分支當前所指的對象。 提供這一功能的參數是 --decorate。 ~~~ $ git log --oneline --decorate f30ab (HEAD, master, testing) add feature #32 - ability to add new 34ac2 fixed bug #1328 - stack overflow under certain conditions 98ca9 initial commit of my project ~~~ 正如你所見,當前 “master” 和 “testing” 分支均指向校驗和以 f30ab 開頭的提交對象。 ## 分支切換 要切換到一個已存在的分支,你需要使用 git checkout 命令。 我們現在切換到新創建的 testing 分支去: `$ git checkout testing` 這樣 HEAD 就指向 testing 分支了。 ![Figure 14. HEAD 指向當前所在的分支](https://box.kancloud.cn/6d156e10bc3c93545af06901b2add7b1_800x460.png) 那么,這樣的實現方式會給我們帶來什么好處呢? 現在不妨再提交一次: ~~~ $ vim test.rb $ git commit -a -m 'made a change' ~~~ ![Figure 15. HEAD 分支隨著提交操作自動向前移動](https://box.kancloud.cn/d1a980043d000afb99ea9345ddf1d3fe_800x334.png) 如圖所示,你的 testing 分支向前移動了,但是 master 分支卻沒有,它仍然指向運行 git checkout 時所指的對象。 這就有意思了,現在我們切換回 master 分支看看: `$ git checkout master` ![Figure 16. 檢出時 HEAD 隨之移動](https://box.kancloud.cn/bb59c55a2ca2426db99660b2d6ad5c7e_800x334.png) 這條命令做了兩件事。 一是使 HEAD 指回 master 分支,二是將工作目錄恢復成 master 分支所指向的快照內容。 也就是說,你現在做修改的話,項目將始于一個較舊的版本。 本質上來講,這就是忽略 testing 分支所做的修改,以便于向另一個方向進行開發。 >Note 分支切換會改變你工作目錄中的文件 在切換分支時,一定要注意你工作目錄里的文件會被改變。 如果是切換到一個較舊的分支,你的工作目錄會恢復到該分支最后一次提交時的樣子。 如果 Git 不能干凈利落地完成這個任務,它將禁止切換分支。 * * * * * 我們不妨再稍微做些修改并提交: ~~~ $ vim test.rb $ git commit -a -m 'made other changes' ~~~ 現在,這個項目的提交歷史已經產生了分叉(參見 項目分叉歷史)。 因為剛才你創建了一個新分支,并切換過去進行了一些工作,隨后又切換回 master 分支進行了另外一些工作。 上述兩次改動針對的是不同分支:你可以在不同分支間不斷地來回切換和工作,并在時機成熟時將它們合并起來。 而所有這些工作,你需要的命令只有 `branch、checkout` 和 `commit`。 ![Figure 17. 項目分叉歷史](https://box.kancloud.cn/a389c84e1e8c8192cade210aa111fe5a_800x512.png) 你可以簡單地使用 git log 命令查看分叉歷史。 運行 `git log --oneline --decorate --graph --all `,它會輸出你的提交歷史、各個分支的指向以及項目的分支分叉情況。 ~~~ $ git log --oneline --decorate --graph --all * c2b9e (HEAD, master) made other changes | * 87ab2 (testing) made a change |/ * f30ab add feature #32 - ability to add new formats to the * 34ac2 fixed bug #1328 - stack overflow under certain conditions * 98ca9 initial commit of my project ~~~ 由于 Git 的分支實質上僅是包含所指對象校驗和(長度為 40 的 SHA-1 值字符串)的文件,所以它的創建和銷毀都異常高效。 創建一個新分支就相當于往一個文件中寫入 41 個字節(40 個字符和 1 個換行符),如此的簡單能不快嗎? 這與過去大多數版本控制系統形成了鮮明的對比,它們在創建分支時,將所有的項目文件都復制一遍,并保存到一個特定的目錄。 完成這樣繁瑣的過程通常需要好幾秒鐘,有時甚至需要好幾分鐘。所需時間的長短,完全取決于項目的規模。而在 Git 中,任何規模的項目都能在瞬間創建新分支。 同時,由于每次提交都會記錄父對象,所以尋找恰當的合并基礎(譯注:即共同祖先)也是同樣的簡單和高效。 這些高效的特性使得 Git 鼓勵開發人員頻繁地創建和使用分支。 接下來,讓我們看看你為什么應該這樣做。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看