问题描述
比方说,我在本地存储区中,其分支为my_name/branch_A
Let's say that I am on a local repo and its branch is my_name/branch_A
当我执行git rebase <branch_B>
时,有时会在未修改的文件中遇到很多冲突.
When I do git rebase <branch_B>
, I sometimes get many conflicts in the files that I did not modify.
为什么会这样?我只想从branch_B
获取所有文件的HEAD,除了我在my_name/branch_A
中修改过的文件之外.如何在不手动解决我没有自我介绍的这些冲突的情况下完成此工作.
Why does this happen?I like to just get the HEAD of all the files from branch_B
except for the ones I modified in my_name/branch_A
. How can this be done without manually resolving these conflicts that I did not introduce myself.
推荐答案
重置副本提交(然后放弃原始文档).这是问题的根源.
Rebase copies commits (and then abandons the originals). This is the root of the problem.
让我们看一个例子.首先,请注意,我绘制的提交图的左侧是较旧的提交,而右侧则是较新的提交.提交在此处具有单字母名称,而不是Git的真正的40个字符的哈希名称,例如f1c93ab7...
.分支名称显示在右侧,带有指向该分支的 tip commit 的箭头,因为这是Git实际存储这些内容的方式.
Let's look at an example. First, note that I'm drawing commit graphs with older commits towards the left, and newer commits towards the right. The commits have single-letter names here, instead of Git's true 40-character hash names like f1c93ab7...
. Branch names appear on the right, with an arrow pointing to the tip commit of that branch, because that is how Git actually stores these things.
您当前的分支名称为my_name/branch_A
,并且您也有一个名为branch_B
的分支.每个分支上有一些提交不在另一个分支上,而某些提交在两个分支上.同时,您的分支my_name/branch_A
从第三点分叉-因此分支上的提交不在branch_B
上,但不是您的提交":
Your current branch name is my_name/branch_A
, and you have a branch named branch_B
as well. There are some commits on each branch that are not on the other branch, and some commits that are on both branches. Meanwhile your branch, my_name/branch_A
, forks off from some third point—so there are commits on your branch that are not on branch_B
, but are not "your commits":
...--A--B--C--D--E <-- branch_uhoh
\ \
\ I--J <-- my_name/branch_A
\
F--G--H <-- branch_B
您已经进行了提交I
和J
,现在您希望让这两个提交在提交H
之后进行,即,将提交重新处理为在branch_B
的提示之后.
You made commits I
and J
and now you would like to have those two commits come after commit H
, i.e., to rework your commits to be "after" the tip of branch_B
.
换句话说,您没有进行提交C--D--E
.但是,这些提交在您的分支上.实际上,提交A
和B
也在您的分支上:这两个提交在 all 分支上.
In other words, you did not make commits C--D--E
. Nonetheless, these commits are on your branch. In fact, commits A
and B
are on your branch too: those two commits are on all the branches.
如果现在运行git rebase branch_B
(仍在分支上),则Git必须弄清楚两件事:
If you now run git rebase branch_B
(while you're still on your branch), Git has to figure out two things:
- 要复制的内容,并且
- 从何处开始放置副本.
名称branch_B
告诉Git 这两个东西.要复制的提交是那些在my_name/branch_A
上但不在branch_B
上的提交.就是C-D-E-I-J
.放置它们的位置是"在branch_B
的最尖端提交之后,即,在H
提交之后.
The name branch_B
tells Git both of these things. The commits to be copied are "those that are on my_name/branch_A
but not on branch_B
. That's C-D-E-I-J
. The place to put them is "after the tip commit of branch_B
, i.e., after commit H
.
如果这一切都成功了,那么Git会将您的分支名称设置为指向新副本:
If this all succeeds, Git would set your branch name to point to the new copies:
...--A--B--C--D--E <-- branch_uhoh
\ \
\ I--J [abandoned]
\
F--G--H <-- branch_B
\
C'-D'-E'-I'-J' <-- my_name/branch_A
带有撇号"标记的名称(C'
等)是副本.
The names with the "prime" marks (C'
and so on) are the copies.
(您可以查看git rebase
将会/将使用git log <upstream>..HEAD
复制的提交,在这种情况下为git log branch_B..HEAD
.在大多数情况下,我会在此处添加--oneline
以获得每行的单行日志消息提交.)
(You can view the commits that git rebase
would/will copy with git log <upstream>..HEAD
, which in this case is git log branch_B..HEAD
. I would add --oneline
here in most cases to get a one-line log message per commit.)
好吧,如果这是问题所在,您应该怎么办?显而易见的答案是:告诉Git不要复制C-D-E
.您想要此结果:
Well, if that's the problem, what should you do? The obvious answer is: tell Git not to copy C-D-E
. You want this result instead:
...--A--B--C--D--E <-- branch_uhoh
\ \
\ I--J [abandoned]
\
F--G--H <-- branch_B
\
I'-J' <-- my_name/branch_A
也就是说,Git应该只在branch_uhoh
的尖端和您的分支之间(实际上在之后)复制那些提交,以便获得I
和J
提交;但应将它们复制到(再次,实际上是)branch_B
的提示.这样做的方法是编写:
That is, Git should copy only those commits "between" (after, really) the tip of branch_uhoh
and your branch, so as to get commits I
and J
; but it should copy them to (again, after, really) the tip of branch_B
. The way to do that is to write:
git rebase --onto branch_B branch_uhoh
换句话说,告诉这两个东西都变基了,而不是告诉一个东西并让它从中找出两个.
In other words, tell rebase both things, instead of telling it one thing and letting it figure out the two from that.
(但是如何找到branch_uhoh
?好吧,正确"的方法通常是记住,但是您可以运行git log --graph --decorate --oneline
并通过其ID查找截止提交或您可以让 Git本身记住您的上游"名称,而不是branch_uhoh
,您可以剪切并粘贴实际截止提交的哈希ID. ,并且只在上游内部和上游建立基础,并且需要 no 参数:只需运行git rebase
即可完成所有工作,但是在某些特殊情况下,需要移植提交,还不够;那么您需要git rebase --onto
.)
(But how do you find branch_uhoh
? Well, the "right" way is usually to remember it, but you can just run git log --graph --decorate --oneline
and find the cutoff commit by its ID or any name that shows up. Instead of branch_uhoh
you can cut-and-paste the hash ID of the actual cutoff commit. Most often, you can have Git itself remember the "upstream" name for you, and you rebase only within and onto the upstream and you need no arguments: you just run git rebase
and it does all the work. But there are special cases where you need to transplant commits, where this is not sufficient; then you need git rebase --onto
.)
这篇关于为什么git rebase在我未修改的文件中显示冲突?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!