Git 分支 - 分支的新建與合並


簡單總結:

1.想在基於當前分支#12基礎上拉新分支進行開發,從當前分支拉copy開發分支#15:

$git checkout -b #15

2.把新建的分支push到遠端,才會在遠程倉庫顯示:

$git push origin #15

3.提交新分支#15的修改后,想合並到拉出來的分支#12,則切換到#12分支,進行merge操作:

$ git merge #15

4.如果覺得之后#15分支不再使用,可以進行刪除:

$ git branch -d #15

 

git查看當前分支所屬:

1、git branch -vv

2、git config --lis

git查看各個branch之間的關系圖

1.  使用git log命令:

git log --graph --decorate --oneline --simplify-by-decoration --all

說明:

--decorate 標記會讓git log顯示每個commit的引用(如:分支、tag等) 

--oneline 一行顯示

--simplify-by-decoration 只顯示被branch或tag引用的commit

--all 表示顯示所有的branch,這里也可以選擇,比如我指向顯示分支ABC的關系,則將--all替換為branchA branchB branchC

2. 使用gitk工具:

gitk --simplify-by-decoration --all

參考:  https://blog.csdn.net/fickyou/article/details/52584161

 

下面來看具體分析:  

首先來看一個簡單的分支新建與分支合並的例子,實際工作中你可能會用到類似的工作流。 你將經歷如下步驟:

  1. 開發某個網站。

  2. 為實現某個新的需求,創建一個分支。

  3. 在這個分支上開展工作。

正在此時,你突然接到一個電話說有個很嚴重的問題需要緊急修補。 你將按照如下方式來處理:

  1. 切換到你的線上分支(production branch)。

  2. 為這個緊急任務新建一個分支,並在其中修復它。

  3. 在測試通過之后,切換回線上分支,然后合並這個修補分支,最后將改動推送到線上分支。

  4. 切換回你最初工作的分支上,繼續工作。

新建分支

首先,我們假設你正在你的項目上工作,並且已經有一些提交。

現在,你決定要解決你的公司使用的問題追蹤系統中的 #53 問題。 想要新建一個分支並同時切換到那個分支上,你可以運行一個帶有 -b 參數的 git checkout 命令:

$ git checkout -b iss53

它是下面兩條命令的簡寫:

$ git branch iss53
$ git checkout iss53

你繼續在 #53 問題上工作,並且做了一些提交。 在此過程中,iss53 分支在不斷的向前推進,因為你已經檢出到該分支(也就是說,你的 HEAD 指針指向了 iss53 分支) 

$ vim index.html
$ git commit -a -m 'added a new footer [issue 53]'

現在你接到那個電話,有個緊急問題等待你來解決。 有了 Git 的幫助,你不必把這個緊急問題和 iss53 的修改混在一起,你也不需要花大力氣來還原關於 53# 問題的修改,然后再添加關於這個緊急問題的修改,最后將這個修改提交到線上分支。 你所要做的僅僅是切換回 master 分支。

但是,在你這么做之前,要留意你的工作目錄和暫存區里那些還沒有被提交的修改,它可能會和你即將檢出的分支產生沖突從而阻止 Git 切換到該分支。 最好的方法是,在你切換分支之前,保持好一個干凈的狀態。 有一些方法可以繞過這個問題(即,保存進度(stashing) 和 修補提交(commit amending)),我們會在 儲藏與清理 中看到關於這兩個命令的介紹。 現在,我們假設你已經把你的修改全部提交了,這時你可以切換回 master 分支了:

$ git checkout master

這個時候,你的工作目錄和你在開始 #53 問題之前一模一樣,現在你可以專心修復緊急問題了。 請牢記:當你切換分支的時候,Git 會重置你的工作目錄,使其看起來像回到了你在那個分支上最后一次提交的樣子。 Git 會自動添加、刪除、修改文件以確保此時你的工作目錄和這個分支最后一次提交時的樣子一模一樣。

接下來,你要修復這個緊急問題。 讓我們建立一個針對該緊急問題的分支(hotfix branch),在該分支上工作直到問題解決:

$ git checkout -b hotfix
Switched to a new branch 'hotfix'
$ vim index.html
$ git commit -a -m 'fixed the broken email address'
[hotfix 1fb7853] fixed the broken email address
 1 file changed, 2 insertions(+)

你可以運行你的測試,確保你的修改是正確的,然后將其合並回你的 master 分支來部署到線上。 你可以使用 git merge 命令來達到上述目的:

$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast-forward
 index.html | 2 ++
 1 file changed, 2 insertions(+)

在合並的時候,你應該注意到了"快進(fast-forward)"這個詞。 由於當前 master 分支所指向的提交是你當前提交(有關 hotfix 的提交)的直接上游,所以 Git 只是簡單的將指針向前移動。 換句話說,當你試圖合並兩個分支時,如果順着一個分支走下去能夠到達另一個分支,那么 Git 在合並兩者的時候,只會簡單的將指針向前推進(指針右移),因為這種情況下的合並操作沒有需要解決的分歧——這就叫做 “快進(fast-forward)”。

現在,最新的修改已經在 master 分支所指向的提交快照中,你可以着手發布該修復了。

關於這個緊急問題的解決方案發布之后,你准備回到被打斷之前時的工作中。 然而,你應該先刪除 hotfix分支,因為你已經不再需要它了 —— master 分支已經指向了同一個位置。 你可以使用帶 -d 選項的 git branch 命令來刪除分支:

$ git branch -d hotfix

現在你可以切換回你正在工作的分支繼續你的工作,也就是針對 #53 問題的那個分支(iss53 分支)。 

$ git checkout iss53
Switched to branch "iss53"
$ vim index.html
$ git commit -a -m 'finished the new footer [issue 53]'
[iss53 ad82d7a] finished the new footer [issue 53]
1 file changed, 1 insertion(+)

你在 hotfix 分支上所做的工作並沒有包含到 iss53 分支中。 如果你需要拉取 hotfix 所做的修改,你可以使用 git merge master 命令將 master 分支合並入 iss53 分支,或者你也可以等到 iss53 分支完成其使命,再將其合並回 master 分支。

分支的合並

假設你已經修正了 #53 問題,並且打算將你的工作合並入 master 分支。 為此,你需要合並 iss53 分支到 master 分支,這和之前你合並 hotfix 分支所做的工作差不多。 你只需要檢出到你想合並入的分支,然后運行 git merge 命令:

$ git checkout master
Switched to branch 'master'
$ git merge iss53
Merge made by the 'recursive' strategy.
index.html |    1 +
1 file changed, 1 insertion(+)

這和你之前合並 hotfix 分支的時候看起來有一點不一樣。 在這種情況下,你的開發歷史從一個更早的地方開始分叉開來(diverged)。 因為,master 分支所在提交並不是 iss53 分支所在提交的直接祖先,Git 不得不做一些額外的工作。 出現這種情況的時候,Git 會使用兩個分支的末端所指的快照(C4 和 C5)以及這兩個分支的工作祖先(C2),做一個簡單的三方合並。

和之前將分支指針向前推進所不同的是,Git 將此次三方合並的結果做了一個新的快照並且自動創建一個新的提交指向它。 這個被稱作一次合並提交,它的特別之處在於他有不止一個父提交。 

需要指出的是,Git 會自行決定選取哪一個提交作為最優的共同祖先,並以此作為合並的基礎;這和更加古老的 CVS 系統或者 Subversion (1.5 版本之前)不同,在這些古老的版本管理系統中,用戶需要自己選擇最佳的合並基礎。 Git 的這個優勢使其在合並操作上比其他系統要簡單很多。

既然你的修改已經合並進來了,你已經不再需要 iss53 分支了。 現在你可以在任務追蹤系統中關閉此項任務,並刪除這個分支。

$ git branch -d iss53

遇到沖突時的分支合並

有時候合並操作不會如此順利。 如果你在兩個不同的分支中,對同一個文件的同一個部分進行了不同的修改,Git 就沒法干凈的合並它們。 如果你對 #53 問題的修改和有關 hotfix 的修改都涉及到同一個文件的同一處,在合並它們的時候就會產生合並沖突:

$ git merge iss53
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.

此時 Git 做了合並,但是沒有自動地創建一個新的合並提交。 Git 會暫停下來,等待你去解決合並產生的沖突。 你可以在合並沖突后的任意時刻使用 git status 命令來查看那些因包含合並沖突而處於未合並(unmerged)狀態的文件: 

$ git status
On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")

Unmerged paths:
  (use "git add <file>..." to mark resolution)

    both modified:      index.html

no changes added to commit (use "git add" and/or "git commit -a")

任何因包含合並沖突而有待解決的文件,都會以未合並狀態標識出來。 Git 會在有沖突的文件中加入標准的沖突解決標記,這樣你可以打開這些包含沖突的文件然后手動解決沖突。 出現沖突的文件會包含一些特殊區段,看起來像下面這個樣子: 

<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github.com</div>
=======
<div id="footer">
 please contact us at support@github.com
</div>
>>>>>>> iss53:index.html

這表示 HEAD 所指示的版本(也就是你的 master 分支所在的位置,因為你在運行 merge 命令的時候已經檢出到了這個分支)在這個區段的上半部分(======= 的上半部分),而 iss53 分支所指示的版本在 ======= 的下半部分。 為了解決沖突,你必須選擇使用由 ======= 分割的兩部分中的一個,或者你也可以自行合並這些內容。 例如,你可以通過把這段內容換成下面的樣子來解決沖突:

<div id="footer">
please contact us at email.support@github.com
</div> 

上述的沖突解決方案僅保留了其中一個分支的修改,並且 <<<<<<< , ======= , 和 >>>>>>> 這些行被完全刪除了。 在你解決了所有文件里的沖突之后,對每個文件使用 git add 命令來將其標記為沖突已解決。 一旦暫存這些原本有沖突的文件,Git 就會將它們標記為沖突已解決。

如果你想使用圖形化工具來解決沖突,你可以運行 git mergetool,該命令會為你啟動一個合適的可視化合並工具,並帶領你一步一步解決這些沖突:

$ git mergetool

This message is displayed because 'merge.tool' is not configured.
See 'git mergetool --tool-help' or 'git help config' for more details.
'git mergetool' will now attempt to use one of the following tools:
opendiff kdiff3 tkdiff xxdiff meld tortoisemerge gvimdiff diffuse diffmerge ecmerge p4merge araxis bc3 codecompare vimdiff emerge
Merging:
index.html

Normal merge conflict for 'index.html':
  {local}: modified file
  {remote}: modified file
Hit return to start merge resolution tool (opendiff):

 如果你想使用除默認工具(在這里 Git 使用 opendiff 做為默認的合並工具,因為作者在 Mac 上運行該程序)外的其他合並工具,你可以在 “下列工具中(one of the following tools)” 這句后面看到所有支持的合並工具。 然后輸入你喜歡的工具名字就可以了。 

等你退出合並工具之后,Git 會詢問剛才的合並是否成功。 如果你回答是,Git 會暫存那些文件以表明沖突已解決: 你可以再次運行 git status 來確認所有的合並沖突都已被解決: 

$ git status
On branch master
All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

Changes to be committed:

    modified:   index.html

如果你對結果感到滿意,並且確定之前有沖突的的文件都已經暫存了,這時你可以輸入 git commit 來完成合並提交。 默認情況下提交信息看起來像下面這個樣子:

Merge branch 'iss53'

Conflicts:
    index.html
#
# It looks like you may be committing a merge.
# If this is not correct, please remove the file
#	.git/MERGE_HEAD
# and try again.


# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# All conflicts fixed but you are still merging.
#
# Changes to be committed:
#	modified:   index.html
#

 如果你覺得上述的信息不夠充分,不能完全體現分支合並的過程,你可以修改上述信息,添加一些細節給未來檢視這個合並的讀者一些幫助,告訴他們你是如何解決合並沖突的,以及理由是什么。

以上轉自   https://git-scm.com/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%9A%84%E6%96%B0%E5%BB%BA%E4%B8%8E%E5%90%88%E5%B9%B6

廖雪峰官網git分支講解:  https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/001375840038939c291467cc7c747b1810aab2fb8863508000

以下轉自:   https://blog.csdn.net/QH_JAVA/article/details/77760499

git從已有分支拉新分支開發:

開發過程中經常用到從master分支copy一個開發分支,下面我們就用命令行完成這個操作:

1. 切換到被copy的分支(master),並且從遠端拉取最新版本:

$git checkout master

$git pull

2. 從當前分支拉copy開發分支:

$git checkout -b dev

3. 把新建的分支push到遠端:

$git push origin dev

4. 拉取遠端分支:

$git pull

There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details.

git pull <remote> <branch>

If you wish to set tracking information for this branch you can do so with:

git branch --set-upstream-to=origin/<branch> dev

經過驗證,當前的分支並沒有和本地分支關聯,根據提示進行下一步:  

5. 關聯:

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

注意:這里branch之后都是沒有空格的,如果有空格則是錯誤命令 

6. 再次拉取 驗證:

$git pull

OK 到此搞定 結束! 

簡單總結:

其實在git中要注意如下幾點:

第一點就是分支,git因分支而強大,所以要理解git中的分支,我們在一個遠程服務下可以拉多個分支,比如生產主分支、測試分支、每個人的開發分支。

第二點就是本地和遠程,當我們在本地建了一個新分支有,還要把新分支推到遠程也就是在遠程建立一樣的一個分支。所以我們在本地和遠程建立分支后還要把他們關聯起來,這樣才有意義!!!

第三點 git遠程服務和git遠程分支,某一個或某幾個分支是在一個服務下的,就好比A項目在遠程的服務是a那么在a服務下我們可以創建 master、test、dev多個測試分支。其實一個遠程服務就是一個project因為在github或gitlab都是創建project。

第四點 當我們從master分支上拉開發分支,我們在自己的開發分支上pull的時候會吧別人提交到master分支的代碼回pull下來,而push的時候還是提交到了自己的開發分支,除非你把自己的開發分支合並到了master分支上。

 

以下轉自:  http://www.cnblogs.com/fengnovo/p/9428463.html

git將當前分支上修改的東西轉移到新建分支

比如我在A分支做了一些修改,現在由於某種原因(如A分支已經合並到master)不能把A分支上修改的東西保留下來但是需要把A分支上修改的東西繼續在新分支繼續修改。那么現在我們可以有兩種簡單的做法完成這一需求。

第一種方法

我們不需要在A分支做commit,只需要在A分支新建B分支,然后切換過去。這個時候你會發現修改的東西在A,B分支都有。這個時候在B分支commit,那么這些修改保留在B分支上,再切換到A分支上會發現修改都沒有保留下來。

第二種方法

使用git stash 將A分支暫存起來,然后在某一個分支(如master分支)新建一個分支B,然后在B分支上使用git stash pop 將修改彈出到B分支上,然后這些修改就在B分支上了。然后我們又可以愉快的玩耍了~


免責聲明!

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



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