如何使用 'git rebase -i' 来重新设置分支中的所有更改?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/363908/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 06:01:39  来源:igfitidea点击:

How do I use 'git rebase -i' to rebase all changes in a branch?

git

提问by semmons99

Here's an example:

下面是一个例子:

>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"

Now I want to do a 'git rebase -i' that will let me rebase all commits for this branch. Is there something like 'git rebase -i HEAD~MASTER' or similar. I figure I could do 'git rebase -i HEAD~2', but I really don't want to have to count how many commits have been made. I could also do 'git rebase -i sha1' but I don't want to comb through git log to find the first commit sha1. Any ideas?

现在我想做一个' git rebase -i',让我重新设置这个分支的所有提交。是否有类似 ' git rebase -i HEAD~MASTER' 或类似的东西。我想我可以做 ' git rebase -i HEAD~2',但我真的不想计算提交的次数。我也可以做 ' git rebase -i sha1' 但我不想通过 git log 来查找第一个提交 sha1。有任何想法吗?

采纳答案by ididak

Have you tried: git rebase -i master?

你有没有试过:git rebase -i master

回答by DanNetwalker

Ok, I'm asuming the branch is called "feature" and it was branched from "master".

好的,我假设分支称为“功能”,它是从“主”分支而来的。

There's this little git command called merge-base. It takes two commits and gives you the first common ancestor of both of those. So...

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

git merge-base feature master

...will give you the first common ancestor of those two commits. Guess what happens when you pass that commit to git rebase -i, like...

...会给你这两个提交的第一个共同祖先。猜猜当您将该提交传递给 git rebase -i 时会发生什么,例如...

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

Interactive rebase from the first common ancestor of both master and feature branch. Profit! ;)

来自 master 和 feature 分支的第一个共同祖先的交互式 rebase。利润!;)

回答by Joost den Boer

The issue with all provided solutions is, they do not allow you to rebase from the very first commit. If the first commit hash is XYZ and you do:

所有提供的解决方案的问题是,它们不允许您从第一次提交开始变基。如果第一个提交哈希是 XYZ 并且您执行以下操作:

git rebase -i XYZ

You only rebase starting from the 2nd commit.

您只能从第二次提交开始变基。

If you want to rebase from the first commit you do:

如果你想从第一次提交变基,你可以:

git rebase -i --root

回答by Otto

Use gitk (*nix), or gitx (OS X) or similar on other platforms, and have a look at which commit was the root of your branch. Then run:

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

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

For example, I have a repository that I inspected using gitx:

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

gitx screencap

gitx 屏幕截图

Now that I know the root hash I can run this:

现在我知道了根哈希,我可以运行这个:

git rebase -i 38965ed29d89a4136e47b688ca10b522b6bc335f

And my editor pops up with this and I can rearrange/squash/whatever as I please.

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

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.
#

I'm sure there's some magic way to convince git to figure out the root of the tree automatically, but I don't know what it is.

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

EDIT: That magic is this:

编辑:那个魔法是这样的:

git log master..other_feature | cat

Which will show you all the commits on that branch, and piping to cat will disable the pager so you see the first commit immediately.

这将向您显示该分支上的所有提交,并且管道到 cat 将禁用寻呼机,因此您可以立即看到第一个提交。

EDIT: combining the above gives a fully automated solution:

编辑:结合以上给出了一个完全自动化的解决方案:

git rebase -i  `git log master..other_feature --pretty=format:"%h" | tail -n 1`~

回答by Seth Flowers

The problem with rebasing from a different branch

从不同的分支变基的问题

The problem with git rebase -i masteris that you may have merge conflicts that you don't necessarily want to deal with at the moment, or you may fix a conflict in one commit, only to fix it again in another commit during the course of the rebase.

问题git rebase -i master在于,您可能有目前不一定要处理的合并冲突,或者您可能在一次提交中修复了冲突,只是在变基过程中在另一次提交中再次修复它。

The problem with rebasing from a known commit

从已知提交变基的问题

The whole problem here is that you have to knowwhich commit you have to refer to, either by its SHA, or HEAD~x, etc. This is only a minor annoyance but it is an annoyance.

这里的整个问题是你必须知道你必须参考哪个提交,通过它的 SHA 或 HEAD~x 等。这只是一个小烦恼,但它是一个烦恼。

The better way

更好的方法

If you instead want to rebase all the commits in your current branch, since the most recent commit it shared with its parent branch, you can add the following alias to .gitconfig:

如果您想重新设置当前分支中的所有提交,因为它与父分支共享了最近的提交,您可以将以下别名添加到 .gitconfig:

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

Usage

用法

git rbi parentBranch

How it works

这个怎么运作

This alias is just a shell script, that is using an argument which refers to the parent branch. That argument is passed into git merge-basein order to determine the most recent shared commit between that branch, and the current branch.

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

回答by Matthieu Moy

Since Git v1.7.10, you can just run git rebasewithout argument, and it will find the fork point and rebase your local changes on the upstream branch.

从 Git v1.7.10 开始,您可以git rebase不加参数地运行,它会找到 fork 点并将您的本地更改重新设置在上游分支上。

You need to have configured the upstream branch for this to work (i.e. git pullwithout argument should work).

您需要配置上游分支才能使其工作(即git pull没有参数应该工作)。

For more details, see the docs for git rebase:

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

If is not specified, the upstream configured in branch..remote and branch..merge options will be used (see git-config[1] for details) and the --fork-point option is assumed. If you are currently not on any branch or if the current branch does not have a configured upstream, the rebase will abort.

如果未指定,将使用在 branch..remote 和 branch..merge 选项中配置的上游(有关详细信息,请参阅 git-config[1])并假定 --fork-point 选项。如果您当前不在任何分支上,或者当前分支没有配置上游,则 rebase 将中止。

回答by Alex Brown

A general solution (if you don't know the name of the upstream branch) is:

一般解决方案(如果您不知道上游分支的名称)是:

git rebase -i @{upstream}

Note that if your upstream (probably a tracking branch) has updated since you last rebased, you will pull in new commits from the upstream. If you don't want to pull in new commits, use

请注意,如果您的上游(可能是跟踪分支)自上次重新定位以来已更新,您将从上游拉入新的提交。如果您不想引入新的提交,请使用

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

but that is a bit of a mouthful.

但这有点难吃。

回答by bbex

git rebase -i --onto @{u}... @{u}

Interactive rebase starting from the single merge point of HEAD and its upstream including all commits in HEAD that are not in its upstream.

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

In other words exactly what you want.

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