git命令行(2)

1、父提交的表示方法

1.HEAD引用

在.git/HEAD目錄下存在一個HEAD文件,其記錄着當前工做區對應的SHA1。若是當前工做區從某個分支檢出(checkout),那麼這個HEAD文件中的引用最終執行分支對應的SHA1,若是處於分離頭狀態(不對應分支,從某個commit檢查),那麼這個HEAD文件中保存的就是檢出的commit SHA1。
git命令行(2)git

若是咱們直接使用git checkout master分支,那麼HEAD的值爲ref: refs/heads/master。指向.git/refs/heads/master文件,其內容就是m6對應的SHA1。
若是咱們使用git checkout ${m4.sha1} ,那麼HEAD的值爲 ${m4.sha1}
所以HEAD引用就是當前工做區對應的提交的SHA1vim

2.父提交的表示方法

可使用~(波浪號)和^號表示父提交,但含義會略有不一樣。
</br>
^表示父提交的第幾個提交,後面若是跟數字就是表示第幾個父提交
例如上圖中當前的工做區HEAD指向m10提交。那麼HEAD^和HEAD^1相同都是指向m9。HEAD^^指向m8,而HEAD^2則是沒有意義的,由於m10只有一個父提交就是m9。HEAD^^^指向是m7,HEAD^^^2指向d2(HEAD^^指向m8,後面的^2表示m8的第二個父提交)。分析^的時候若是^號後面沒有數字則和^1等價,表示第一個父提交,若是存在數字就表示第幾個父提交。
tips:若是^後面的形式如:^{commit},^{tree},^{blob},則表示當前對象的提交、樹、blob對象。
</br>
~表示法:波浪號表示父提交的層次關係。那麼HEAD~和HEAD~1相同都是指向m9。HEAD~ ~指向m8,而HEAD~2和HEAD~\~是徹底等價的。HEAD~\~\~指向是m7,HEAD~3和其等價。所以d2就能夠表示爲HEAD~2^2(HEAD~2指向m8,後面的^2表示m8的第二個父提交),所以若是存在數字表示父提交的父提交的父提交...(數字就是幾層父提交)bash

所以當咱們使用git log命令的時候,能夠打印部分父提交。
git log --oneline HEAD~8..HEAD~5編輯器

3.git reflog

當咱們對任何的分支修改(commit、pull、push)的時候,在.git/logs/refs目錄都會記錄變動狀況,所以徹底不用擔憂提交記錄丟失的狀況。.git/logs/refs/heads記錄本地分支的變動記錄,.git\logs\refs\remotes記錄遠程分支在本地的變動狀況。
當咱們使用git reflog命令的時候就會顯示HEAD引用的變動狀況。
git命令行(2)
一樣能夠經過git reflog master查看master分支的變動狀況。
reflog表示法:HEAD@{1},表示HEAD引用以前的第一個變動。ide

git reset --hard HEAD@{1}。若是新拉取的代碼有問題,可是拉取以前的代碼不肯定是否有問題,須要把代碼回滾到拉取以前的代碼,那麼就能夠執行這個命令測試

2、修改提交

本地提交代碼的時候常常會出現須要更改提交、修改註釋的狀況,下面的幾個命令能夠實現修改提交。命令行

1.git commit

git commit --amend能夠方便的修改當前說起的註釋。當執行這個命令的時候會彈出vim編輯器編輯註釋信息(只修改提交註釋信息)。3d

2.git reset

git reset命令能夠把當前分支重置到某個提交。其選項有三個:日誌

  • --hard:把工做區、暫存區的內容也重置到該提交
  • --mixed:默認選項,把暫存器的內容重置到該提交,可是保留當前工做區的內容
  • --soft:工做區、暫存器保留原來的內容,分支的引用重置到某個提交

3.git revert

若是咱們的提交已經push到遠程倉庫上,別人已經pull下來了,若是你想刪除某次提交,reset就不能使用了,而是使用revert命令,revert即對某次提交產生一個副作用的提交。code

git revert HEAD~3 -----建立一個提交,回滾最近的第四次提交
git revert  master~5..master~2  ---回滾某個範圍的提交

4.git rebase

git rebase能夠對當前沒有push的提交進行更改,設想一下一個功能你能夠本地進行了屢次提交,可是push的時候你想把這些提×××併成一個,就可使用git rebase命令編輯提交。
假設咱們須要對以下m9-m13的提交編輯。
git命令行(2)
場景一:把這些提交併成一個提交
git命令行(2)
使用squash命令和上一個提×××並,而後從新修改提交日誌

場景二:刪除某個提交
刪除某個提交直接把該提交對應的行去除或者使用remove命令。若是存在合併衝突,而後解決衝突。

git命令行(2)
根據git命令行的提示,解決完衝突之後運行git add添加衝突的修改。

場景三:修改某個提交的日誌:
使用edit命令或者reword命令修改,最好使用reword命令,這樣rebase就能夠之間彈出修改日誌的vim編輯器,而不用git 彈出git commit --amend提示。

3、分支標籤命令

1.git branch

使用branch命令能夠管理分支。

$ git branch                ------顯示本地分支
$git branch -a            -------顯示本地和遠程分支
$git branch xxxbranchName -------建立分支名xxxbranchName的分支,此時HEAD的引用仍然是指向原來的分支
$git branch -d xxxbranchName   ---刪除某一個分支,若是該分支的修改沒有合併,那麼刪除失敗
$git branch -D xxxbranchName -----強制刪除分支

2.git tag

使用tag命令能夠管理標籤。標籤和分支的區別是,標籤是不能夠修改的。若是要修改必須基於該標籤拉出一個分支修改

$git tag -------------展現全部的tag
$git tag xxxtagName ---------------新建xxxtagName的標籤
$git tag -d xxxtagName ---------刪除xxxtagName的標籤

3.git checkout

checkout命令能夠檢出某個提交或者分支。

$git checkout SHA-1           ----------檢出某個SHA-1對應的提交
$git checkout xxxbranchName -------------咱們使用git branch xxxbranchName的時候只是新建了這個分支,須要執行該命令切換到該分支
$git checkout HEAD^               -----檢出到HEAD的第一個父提交
$git checkout -b xxxbranchName -------------新建xxxbranchName並檢出到該分支

當咱們checkout除分支外的其餘SHA-1都會提示咱們處於detached HEAD狀態,此時.git/HEAD文件裏面的內容就是SHA-1
git命令行(2)
此時若是在分離頭上作的修改和提交想合併到其餘分支須要用到merge和rebase等命令

4、合併命令

1.git merge

merge命令能夠合併兩個多個提交,並生成一個新的提交。當前分支始終是目標分支。
假設歷史記錄以下,且當前分支爲master:

A---B---C topic
     /
    D---E---F---G master

而後運行 "git merge topic",將會產生一個新的提交H,其中H的父提交是C和G。

A---B---C topic
     /              \
    D---E---F---G---H master
$ git merge fixes enhancements 能夠合併多個分支到當前分支
$git merge 8b9612d76178416c06da3b76cfab2945ddc98347    ----合併某個提交

合併中衝突的處理:

$ git merge feture1
Auto-merging gameoflife-deploy/pom.xml
CONFLICT (content): Merge conflict in gameoflife-deploy/pom.xml
Automatic merge failed; fix conflicts and then commit the result.

merge命令能夠一次性把全部衝突的文件合併,而後提示用戶合併衝突去解決。解決完衝突之後,須要運行git add命令把文件添加到暫存區。繼續執行git merge --continue命令編輯新生成的提交的log信息。而後merge完成。

2.git rebase

rebase命令除了能夠更改提交之外,同時能夠合併代碼,不過和merge命令有些不一樣。
假設歷史記錄以下,且當前分支爲topic:

A---B---C topic
         /
 D---E---F---G master

那麼運行git rebase master的時候,其提交以下:

A'--B'--C' topic
                        /
    D---E---F---G master

其中A'、B'、C'和A、B、C已經不是同一個提交(其tree對象不是同一個,父提交也不是同一個),可是其修改的內容是相同的。
rebase命令合併的時候從兩個分支(或者提交)公共的父提交開始變基。
整體變基命令用的很少,並且場景比較複雜(能夠查看其help文檔)。慎用

3.merge和rebase的區別

一、merge命令會產生一個合併提交,而變基不會。變基命令的提交樹會比較清晰,merge存在各類合併,看着比較混亂。
二、工做流不一樣,對於merge命令其合併是全部提交一次合併好,而後解決衝突,而變基命令只能一個提交一個提交的解決衝突。

merge:merge的時候把待合併的全部commit一次合併好,只顯示一次衝突,解決完衝突之後運行一次git merge --continue就行。
rebase:  工做流程大概以下:
             commit =nextNeedMergeCommit()
              while(merge(commit)==confict)
                            {
                                resoveConfilec();
                                    rebaseContinue();
                                    commit =nextNeedMergeCommit()
                            }

4.Fast-forward快進式合併

在合併的時候常常會遇到快進式合併,那麼什麼是快進式合併麼?
假設存在以下的場景:

A---B---C topic
         /
 D---E           master
那麼咱們執行git merge topic命令的時候,其結果就是快進式合併以下:
D---E --- A---B---C          master

而若是執行git merge topic --no-ff 非快進式提交,測試以下的結果以下:

A---B---C
         /              \
D---E --------------M          master

會多產生一個提交M,其父提交爲E和C。

5.git cherry-pick

可使用cherry-pick摘取每一個提交的內容,併合並當前分支
假設歷史記錄以下,且當前分支爲topic:

A---B---C topic
         /
 D---E---F---G master

假設咱們指向合併A、B到master分支,那麼就可使用cherry-pick命令

$git cherry-pick topic~2 topic~1
          A---B---C topic
         /
 D---E---F---G-----A'---B' master

若是出現合併衝突,一樣須要處理衝突,而後使用git cherry-pick --continue命令繼續

6.git如何追蹤衝突

當出現衝突的時候:

  • .git/MERGE_HEAD 記錄合併進來的提交的SHA1值。
  • .git/MERGE_MSG包含當解決衝突之後執行git commit後默認的消息日誌
  • git的索引(暫存區)裏面每一個衝突文件的三個副本:合併基礎、「咱們的」版本和「他們的版本」。給這三個副本分配了各自的編號一、二、3.
  • 衝突的版本(合併標記和全部內容)不存儲在暫存區內。

可使用git ls-files -u命令查看衝突的文件。
git命令行(2)

相關文章
相關標籤/搜索