Git rebase使用


rebase的優點和缺點

優點

  • rebase最大的好處是你的項目歷史會非常整潔
  • rebase 導致最后的項目歷史呈現出完美的線性——你可以從項目終點到起點瀏覽而不需要任何的 fork。這讓你更容易使用 git log、git bisect 和 gitk 來查看項目歷史

缺點

  • 安全性,如果你在公共分支上使用rebase,重寫項目歷史可能會給你的協作工作流帶來災難性的影響
  • 可跟蹤性,rebase會更改歷史記錄,rebase 不會有合並提交中附帶的信息——你看不到 feature 分支中並入了上游的哪些更改

分支內合並多個commit為一個新commit使用:

命令:

這里我們使用命令:

  git rebase -i  [startpoint]  [endpoint]

其中-i的意思是--interactive,即彈出交互式的界面讓用戶編輯完成合並操作,[startpoint] [endpoint]則指定了一個編輯區間,如果不指定[endpoint],則該區間的終點默認是當前分支HEAD所指向的commit(注:該區間指定的是一個前開后閉的區間)。

使用:

log日志:

D:\Git\shell-demo (master -> origin)
$ git l
* d7a7c8f - (HEAD -> master) cc (33 minutes ago) | hongda
* dbe4bac - bb (33 minutes ago) | hongda
* 439e203 - aa (34 minutes ago) | hongda
* 5b38c9e - init (8 months ago) | hongqi

執行rebase命令:

$ git rebase -i 5b38c9e

或者:

$ git rebase -i HEAD~3

彈出的vim界面:

pick 439e203 aa
pick dbe4bac bb
pick d7a7c8f cc

# Rebase 5b38c9e..d7a7c8f onto 5b38c9e (3 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# .       create a merge commit using the original merge commit's
# .       message (or the oneline, if no original merge commit was
# .       specified). Use -c <commit> to reword the commit message.
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
D:/Git/shell-demo/.git/rebase-merge/git-rebase-todo [unix] (16:23 24/12/2018)

上面未被注釋的部分列出的是我們本次rebase操作包含的所有提交,下面注釋部分是git為我們提供的命令說明。每一個commit id 前面的pick表示指令類型,git 為我們提供了以下幾個命令:

  • pick:保留該commit(縮寫:p)
  • reword:保留該commit,但我需要修改該commit的注釋(縮寫:r)
  • edit:保留該commit, 但我要停下來修改該提交(不僅僅修改注釋)(縮寫:e)
  • squash:將該commit和前一個commit合並(縮寫:s)
  • fixup:將該commit和前一個commit合並,但我不要保留該提交的注釋信息(縮寫:f)
  • exec:執行shell命令(縮寫:x)
  • drop:我要丟棄該commit(縮寫:d)

修改為:

pick 439e203 aa
s dbe4bac bb
s d7a7c8f cc

在彈出下面的界面,可以修改注釋

# This is a combination of 3 commits.
# This is the 1st commit message:

modify file

# This is the commit message #2:

bb

# This is the commit message #3:

cc

# Please enter the commit message for your changes. Lines starting

再次查看日志:

D:\Git\shell-demo (master -> origin)
$ git l
* 7e09cf2 - (HEAD -> master) modify file (69 seconds ago) | hongda
* 5b38c9e - init (8 months ago) | hongqi

多個commitid合並成了一個新的commitid

將其他分支合並到主分支,表現為線性:

mm分支:

D:\Git\shell-demo (mm -> origin)
$ git l
* 01dc337 - (HEAD -> mm) c (7 seconds ago) | hongda
* 1719011 - b (18 seconds ago) | hongda
* 588069c - a (34 seconds ago) | hongda
* 5b38c9e - init (8 months ago) | hongqi

master分支:

D:\Git\shell-demo (master -> origin)
$ git l
* 5b38c9e - init (8 months ago) | hongqi

合並:

D:\Git\shell-demo (master -> origin)                                                                      
$ git rebase mm                                                                                           
First, rewinding head to replay your work on top of it...                                                 
Fast-forwarded master to mm.                                                                              
                                                                                                                                                                             
D:\Git\shell-demo (master -> origin)                                                                      
$ git l                                                                                                   
* 01dc337 - (HEAD -> master, mm) c (57 seconds ago) | hongda                                              
* 1719011 - b (68 seconds ago) | hongda                                                                   
* 588069c - a (84 seconds ago) | hongda                                                                                                                                                                    
* 5b38c9e - init (8 months ago) | hongqi                                                                                                                      

如果rebase有沖突,跟merge一樣解決沖突提交即可。

將其他分支多個commit合並到主分支,並形成一個新commit:

我不建議這么使用,除非這里的分支合並完以后就不使用了,不然的話,以后有新的提交,再次合並,很可能忘記從那個commit開始合並。

命令:

我們使用命令的形式為:

    git rebase   [startpoint]   [endpoint]  --onto  [branchName]

其中,[startpoint] [endpoint]仍然和上一個命令一樣指定了一個編輯區間(前開后閉),--onto的意思是要將該指定的提交復制到哪個分支上。

所以,在找到C(90bc0045b)和E(5de0da9f2)的提交id后,我們運行以下命令:

    git  rebase   90bc0045b^   5de0da9f2   --onto master

注:因為[startpoint] [endpoint]指定的是一個前開后閉的區間,為了讓這個區間包含C提交,我們將區間起始點向后退了一步

使用:

mm分支:

D:\Git\shell-demo (mm -> origin)
$ git l
* 88dc407 - (HEAD -> mm) e (3 seconds ago) | hongda
* 9cc37e9 - d (14 seconds ago) | hongda
* 01dc337 - c (2 hours ago) | hongda
* 1719011 - b (2 hours ago) | hongda
* 588069c - a (2 hours ago) | hongda
* 5b38c9e - init (8 months ago) | hongqi

master分支:

$ git l
* 41fd42b - (HEAD -> master) modify file for aa commit (39 seconds ago) | hongda
* 5b38c9e - init (8 months ago) | hongqi

rebase命令:

git rebase 588069c  88dc407  --onto master

合並b,c,d,e四個提交到master,注意並不包括a

First, rewinding head to replay your work on top of it...
Applying: b
Using index info to reconstruct a base tree...
M       asd.txt
Falling back to patching base and 3-way merge...
Auto-merging asd.txt
CONFLICT (content): Merge conflict in asd.txt
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch' to see the failed patch
Patch failed at 0001 g
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".

如果合並過程中遇到沖突,就解決沖突,並add,再繼續rebase

D:\Git\shell-demo (HEAD detached at 80f8fc3 -> origin)
$ git aa

D:\Git\shell-demo (HEAD detached at 80f8fc3 -> origin)
$ git rebase --continue

多個合並沖突就會合並多次,合並多次就會產生多個commit,跟我想只有一個commit的意願違背,非常不喜歡

注意,沖突就會切換到游離分支,解決辦法就是創建一個臨時分支,用完再刪除。

參考:

rebase

【Git】rebase 用法小結

Git rebase詳細解析


免責聲明!

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



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