Git-为什么开发分支和主分支之间存在冲突

Git-为什么开发分支和主分支之间存在冲突,git,Git,我有两个分支:master分支和development 到目前为止,develope和master几乎是一样的。 从现在起,我想将所有的修补程序推送到master中,并将新功能推送到develope,但我还需要确保develope拥有master中的所有修补程序 我通常做的是: 用于修复: 从master分支:git checkout-b fix/my fix。 当我完成开发时,我执行一个git push origin/my fix,然后使用Gitlab Merge请求将my fix合并到mas

我有两个分支:
master
分支和
development

到目前为止,
develope
master
几乎是一样的。 从现在起,我想将所有的
修补程序
推送到
master
中,并将新功能推送到
develope
,但我还需要确保
develope
拥有
master
中的所有修补程序

我通常做的是:

用于修复: 从
master
分支:
git checkout-b fix/my fix
。 当我完成开发时,我执行一个
git push origin/my fix
,然后使用Gitlab Merge请求将
my fix
合并到
master

对于新功能1: 从我的
master
分支,我做了:
git checkout-b feature/new-feature-1
,然后
new feature
在一段时间后被推入
develope
。 在进入
develope
之前,我做了一个
git-rebase-master
(在
git-pull-origin-master
分支上的
git-pull-master
之前),以确保
develope
将得到
master
更改

对于新功能2: 从我的
develope
分支,我做了:
git checkout-b feature/new-feature-2
,然后
new-feature-2
在一段时间后被推入
develope
。在推进开发之前,我再次使用了
git-rebase-master

现在,我已经将一个
fix2
推到master中,当我转到我的
develope
分支并执行
git-rebase-master
时,我有很多冲突,我不知道为什么。 如果我经常在
develope
上使用
git-rebase-master
,怎么会发生这种情况? 我做错什么了吗? 我有时也会收到一条消息,说我的分支

在一个
git rebase master
之后,我得到的信息是:

rebase in progress; onto 23ddfcc1
You are currently rebasing branch 'develop' on '23ddfcc1'.
  (fix conflicts and then run "git rebase --continue")
  (use "git rebase --skip" to skip this patch)
  (use "git rebase --abort" to check out the original branch)
develope
的图表给出:

*   commit 9fc59e3a5b1de6d93c2f9560ba0a758fb507b672 (HEAD -> develop)
|\  Merge: b620adef 23ddfcc1
| | Author: 
| | Date:   Wed Sep 30 23:38:51 2020 +0200
| |
| |     Merge branch 'master' of '' into develop
| |
| *   commit 23ddfcc15ea7a7ad9d5f8c45d386e78c9b6bbf8c (origin/master, origin/HEAD, master)
| |\  Merge: 572e5a9d 1833bf1f
| | | Author: 
| | | Date:   Wed Sep 30 23:13:08 2020 +0200
| | |
| | |     Merge branch 'fix/FIX-1/some-name' into 'master'
| | |
| | |     
| | |
| | |     See merge request XX!322
| | |
| | * commit 1833bf1f84433ecf4fe4a1f707b891ed6c3ea0b0 (origin/fix/FIX-2/some-error, fix/FIX-2/some-error)
| |/  Author: 
| |   Date:   Wed Sep 30 14:04:56 2020 +0200
| |
| |      
| |
* |   commit b620adef2ec7d2cce5d9e75acea51554f3735f9f (origin/develop)
|\ \  Merge: 11e48497 dc8d2433
| | | Author: 
| | | Date:   Wed Sep 30 16:37:39 2020 +0200
| | |
| | |     Merge branch 'develop'  into develop
| | |
| * |   commit dc8d2433d80385e011845a76b6536732c824dacc
| |\ \  Merge: db14ba4d dd0c8698
| | | | Author: 
| | | | Date:   Wed Sep 30 16:29:55 2020 +0200
| | | |
| | | |     Merge branch 'feature/FEATURE1/contact-form' into 'develop'
| | | |
| | | |   
| | | |
| | | |     See merge request !318
| | | |
| | * | commit dd0c8698c84e67adaed4dd1d477e6f9fb4e1bbf8 (origin/feature/FEATURE1/contact-form, feature/FEATURE1/contact-form)
| | | | 
| | | | Date:   Mon Sep 28 12:04:17 2020 +0200


我仍然不清楚问题是什么,但我认为它是:“对于只存在于我们正在重定基址的分支中的文件,在重定基址过程中怎么会有冲突?”所以我将回答这个问题


什么是重基?这基本上是一个重复的樱桃采摘

什么是樱桃树?这是一种合并。这是一个补丁的应用程序合并,它是一个diff的表达式

考虑以下情况:

A - B - C (master)
    |
    X - Y (feature)
假设您使用的是feature,您说的是git rebase master。这是什么意思

这里的目标是将X和Y“移动”到C上;实际上,我们将创建新的提交X'和Y',有效地复制X和Y所做的事情。这怎么可能

好的,从X的父,也就是B开始。B和X之间有一些区别,也就是说,你必须对B做一些事情,才能从B到X。好的,对C做同样的“事情”,这会给我们X’

好的,为了简单起见,假设这个repo中只有一个文件,A.txt。它出现在commit B中,假设X在a.txt后面加了一行。但是假设C删除了A.txt

因此,从端点的角度来看,正如您所说,A.txt只存在于
功能中。但从合并的角度来看,即尝试将更改B->X“重放”为更改C->X”,不清楚如何继续。C没有A.txt;同时,X假定存在一个它编辑的.txt

这是一场冲突

$ git init
$ echo howdy > A.txt
$ git add A.txt
$ git commit -m"A"
$ echo howdy >> A.txt
$ git commit -a -m"B"
$ git branch feature # but don't get on it yet
$ git rm A.txt
$ git commit -a -m"C"
$ ls # crickets... ok, time for the branch
$ git checkout feature
$ ls
A.txt
$ echo yoho >> A.txt
$ git commit -a -m"X"
$ echo yoho >> A.txt
$ git commit -a -m"Y"
$ cat A.txt
howdy
howdy
yoho
yoho
$ git log --oneline
3308220 (HEAD -> feature) Y
f829812 X
ede9af5 B
a2a98f2 A
$ git log --oneline master
2dfe0fb (master) C
ede9af5 B
a2a98f2 A
现在,我将执行该场景,创建我在上面绘制的图表,然后我将重新设置基准以显示冲突

$ git init
$ echo howdy > A.txt
$ git add A.txt
$ git commit -m"A"
$ echo howdy >> A.txt
$ git commit -a -m"B"
$ git branch feature # but don't get on it yet
$ git rm A.txt
$ git commit -a -m"C"
$ ls # crickets... ok, time for the branch
$ git checkout feature
$ ls
A.txt
$ echo yoho >> A.txt
$ git commit -a -m"X"
$ echo yoho >> A.txt
$ git commit -a -m"Y"
$ cat A.txt
howdy
howdy
yoho
yoho
$ git log --oneline
3308220 (HEAD -> feature) Y
f829812 X
ede9af5 B
a2a98f2 A
$ git log --oneline master
2dfe0fb (master) C
ede9af5 B
a2a98f2 A
很好,我们已经准备好再基地了

$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: X
Using index info to reconstruct a base tree...
A   A.txt
Falling back to patching base and 3-way merge...
CONFLICT (modify/delete): A.txt deleted in HEAD and modified in X. 
 Version X of A.txt left in tree.
error: Failed to merge in the changes.
Patch failed at 0001 X
hint: Use 'git am --show-current-patch' to see the failed patch
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".
因此,重新设置基址的顺序良好。最后,请仔细观察重新基址前后X和Y的SHA,您将看到重新基址后的X和Y确实与重新基址前的X和Y不同。“旧的”X和Y仍然存在,但由于现在没有任何东西指向它们,它们很可能最终会被清理干净



那么这里的教训是什么?为了将该功能重新设置到主功能上,我们从在该功能开始之前提交开始。然后,我们必须考虑大师在那一点之后的整个历史,同时,从那一点到第一次提交特征的历史。如果我们不能将这两个历史记录作为自动合并来解决,那就是冲突,我们需要用户的帮助。等等,通过每一次提交功能。

你一直在说“推入”。Git以特定的方式使用术语“push”,但后面不能跟“into”。你是说“合并”吗?如果你这样做了,你总是指一个真正的合并和一个合并提交,还是一个虚假的GitHub“合并”,实际上是一个重基或挤压?我想从你的图表中可以看出,你通常指的是真正的合并,但清楚一点很重要。嗨@matt,是的,我指的是真正的合并。好吧,我已经可以建议,如果你在创建新分支时开始的分支是你将要合并新分支的分支,那么你的生活会好得多。签出master,创建一个新分支,然后签出开发和合并那个新分支,这是一个困难的配方,因为合并是什么。是的,我同意。但这只是为了功能1。当我意识到我从错误的分支开始时,已经太晚了。但是,对于feature2,我从开发开始为开发。好的,那么问题到底是什么?是不是因为你对重设基础会导致冲突感到惊讶?