代码之家  ›  专栏  ›  技术社区  ›  semmons99

如何使用“git rebase-I”对分支中的所有更改进行重基化?

git
  •  90
  • semmons99  · 技术社区  · 16 年前

    这里有一个例子:

    >git status
    # On branch master
    nothing to commit (working directory clean)
    >git checkout -b test-branch
    >vi test.c
    >git add test.c
    >git commit -m "modified test.c"
    >vi README
    >git add README
    >git commit -m "modified README"
    

    现在我想做一个 git rebase -i 这样我就可以为这个分支重新设置所有提交的基础。是否有类似“ git rebase -i HEAD~MASTER ”或类似。我想我能做到 git rebase -i HEAD~2 ,但我真的不想计算已经提交了多少次。我也可以这样做 git rebase -i sha1 但我不想梳理git日志来找到第一个提交sha1。有什么想法吗?

    8 回复  |  直到 16 年前
        1
  •  37
  •   d-_-b    10 年前

    好的,我估计这个分支叫做“特征”,它是从“主”分支出来的。

    有一个名为merge-base的小git命令。它需要两次提交,并为您提供这两次提交的第一个共同祖先。所以。。。

    git merge-base feature master
    

    …会给你这两个提交的第一个共同祖先。猜猜当你把这个commit传递给git rebase-i时会发生什么。..

    git rebase -i `git merge-base feature master`
    

    从主分支和特征分支的第一个共同祖先进行交互式重基。 利润! ;)

        2
  •  59
  •   DanNetwalker    14 年前

    所有提供的解决方案的问题是,它们不允许您从第一次提交开始重设基础。 如果第一个提交哈希是XYZ,并且您这样做:

    git rebase -i XYZ
    

    你只能从第二次提交开始重设基础。

    如果你想从第一次提交中重设基础,你可以这样做:

    git rebase -i --root
    
        3
  •  50
  •   Joost den Boer    10 年前

    你试过: git rebase -i master ?

        4
  •  20
  •   community wiki 4 revs, 3 users 92% Otto    7 年前

    在其他平台上使用gitk(*nix)或gitx(OS X)或类似工具,看看哪个commit是你的分支的根。然后运行:

    git rebase -i <the SHA hash of the root commit>
    

    例如,我有一个使用gitx检查的存储库:

    gitx screencap

    现在我知道了根哈希,我可以运行以下命令:

    git rebase -i 38965ed29d89a4136e47b688ca10b522b6bc335f
    

    我的编辑弹出了这个,我可以随意重新排列/压缩/任何东西。

    pick 50b2cff File 1 changes.
    pick 345df08 File 2 changes.
    pick 9894931 File 3 changes.
    pick 9a62b92 File 4 changes.
    pick 640b1f8 File 5 changes.
    pick 1c437f7 File 6 changes.
    pick b014597 File 7 changes.
    pick b1f52bc File 8 changes.
    pick 40ae0fc File 9 changes.
    
    # Rebase 38965ed..40ae0fc onto 38965ed
    #
    # Commands:
    #  pick = use commit
    #  edit = use commit, but stop for amending
    #  squash = use commit, but meld into previous commit
    #
    # If you remove a line here THAT COMMIT WILL BE LOST.
    # However, if you remove everything, the rebase will be aborted.
    #
    

    我确信有一些神奇的方法可以说服git自动找出树的根,但我不知道它是什么。

    编辑:这个魔术是这样的:

    git log master..other_feature | cat
    

    这将显示该分支上的所有提交,管道连接到cat将禁用分页器,以便您立即看到第一个提交。

    编辑:将上述内容结合起来,可以得到一个完全自动化的解决方案:

    git rebase -i  `git log master..other_feature --pretty=format:"%h" | tail -n 1`~
    
        5
  •  6
  •   Seth Flowers    10 年前

    据我所知,OP的问题

    如果你实际上不想在master之上重基,但你宁愿把所有提交压缩成一个,因为这与master不同。

    从不同分支重设基准的问题

    问题在于 git rebase -i master 你可能有合并冲突,但目前不一定想处理,或者你可能在一个提交中修复了冲突,但在重基过程中又在另一个提交中将其修复。

    从已知提交中重设基础的问题

    这里的问题是,你必须 知道 你必须通过SHA或HEAD~x等引用哪个commit。这只是一个小小的烦恼,但却是一个烦恼。

    更好的方法

    如果你想重新设置当前分支中所有提交的基础,因为最近一次提交与其父分支共享,你可以在.gitconfig中添加以下别名:

    rbi = !sh -c \"git rebase -i `git merge-base $1 HEAD`\" -
    

    使用

    git rbi parentBranch
    

    然后,您可以使用交互式重基来拾取/改写/编辑/挤压/等分支中的所有提交,因为它与父分支不同。我的典型流程是选择最旧的提交(位于顶部的提交),并将所有其他提交设置为f(或修复)。

    工作原理

    这个别名只是一个shell脚本,它使用了一个引用父分支的参数。这个论点被传递到 git merge-base 以便确定该分支和当前分支之间的最新共享提交。

        6
  •  4
  •   Matthieu Moy    10 年前

    从Git v1.7.10开始,你可以直接运行 git rebase 无需争论,它就会找到分叉点,并在上游分支上重新设置本地更改的基础。

    您需要配置上游分支才能正常工作(即。 git pull 没有争论应该奏效)。

    有关更多详细信息,请参阅以下文档 git rebase :

    如果未指定,则上游配置为 支。远程和分支。将使用.merge选项(请参见 git config[1]获取详细信息),并假设使用--fork point选项。如果 您当前不在任何分支上,或者如果当前分支不在 如果配置了上游,则重基将中止。

        7
  •  2
  •   Alex Brown    13 年前

    一个通用的解决方案(如果你不知道上游分支的名称)是:

    git rebase -i @{upstream}
    

    请注意,如果您的上游(可能是一个跟踪分支)自上次重基以来已经更新,您将从上游获取新的提交。如果你不想引入新的提交,请使用

    git rebase -i `git merge-base --all HEAD @{upstream}`
    

    但这有点令人反感。

        8
  •  1
  •   bbex    11 年前
    git rebase -i --onto @{u}... @{u}
    

    交互式重基从HEAD的单个合并点及其上游开始,包括HEAD中不在其上游的所有提交。

    换句话说,正是你想要的。