zoukankan      html  css  js  c++  java
  • 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:Gitshell-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:Gitshell-demo (master -> origin)
    $ git l
    * 7e09cf2 - (HEAD -> master) modify file (69 seconds ago) | hongda
    * 5b38c9e - init (8 months ago) | hongqi
    

    多个commitid合并成了一个新的commitid

    将其他分支合并到主分支,表现为线性:

    mm分支:

    D:Gitshell-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:Gitshell-demo (master -> origin)
    $ git l
    * 5b38c9e - init (8 months ago) | hongqi
    

    合并:

    D:Gitshell-demo (master -> origin)                                                                      
    $ git rebase mm                                                                                           
    First, rewinding head to replay your work on top of it...                                                 
    Fast-forwarded master to mm.                                                                              
                                                                                                                                                                                 
    D:Gitshell-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:Gitshell-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:Gitshell-demo (HEAD detached at 80f8fc3 -> origin)
    $ git aa
    
    D:Gitshell-demo (HEAD detached at 80f8fc3 -> origin)
    $ git rebase --continue
    

    多个合并冲突就会合并多次,合并多次就会产生多个commit,跟我想只有一个commit的意愿违背,非常不喜欢

    注意,冲突就会切换到游离分支,解决办法就是创建一个临时分支,用完再删除。

    参考:

    rebase

    【Git】rebase 用法小结

    Git rebase详细解析

  • 相关阅读:
    艾伟也谈项目管理,BUG平台应该是一个知识库 狼人:
    艾伟也谈项目管理,敏捷的坏态度 狼人:
    艾伟也谈项目管理,关于导致项目失败的程序的讨论 狼人:
    艾伟也谈项目管理,成功软件项目管理的奥秘 狼人:
    艾伟也谈项目管理,如何评估软件进度 狼人:
    艾伟也谈项目管理,敏捷个人:内容框架之执行力 狼人:
    艾伟也谈项目管理,项目管理 – 人员外购利弊谈(续) 狼人:
    艾伟也谈项目管理,ERP项目实施要未雨绸缪不要亡羊补牢 狼人:
    艾伟也谈项目管理,项目管理的十大挑战 狼人:
    艾伟也谈项目管理,项目过程中所遇到的各种问题记录——有关MSChart的一些小技巧 狼人:
  • 原文地址:https://www.cnblogs.com/hongdada/p/10170296.html
Copyright © 2011-2022 走看看