让我详细解释一下这个问题。
我有一个主git分支,我在其上创建了一个新的分支bug10101010,现在我不想将bug10101010合并到main。到目前为止一切都很好。 现在我有一个相同产品的不同分支,名为legacy。我不想将bug10101010合并到GIT中的遗留分支。
有什么想法吗?
我不能直接合并它,因为分支bug10101010是从主分支中分离的,而在遗产中我只需要分支bug10101010与其父分支之间的差异。
答案 0 :(得分:6)
您应在此处使用 git rebase --onto
,并指定范围
(见git rebase
man page:
将基于一个分支的主题分支移植到另一个分支,假设您使用
rebase --onto
从后一分支分叉主题分支。
)。
当然,这会将bug10
分支移到legacy
分支之上,这不是您想要/需要的分支。
因此,一个解决方法是在克隆的回购中执行该rebase,然后合并'增强的'legacy
分支(克隆回购中的那个,{{1在其上面进行修改)到本地和当前bug10
分支(您要修改的分支,同时单独留下legacy
)。
现在:
bug10
分支,因此其他答案(补丁)是有效的(并且更简单)。legacy
提交),然后再将那个分支bug10
推送到原来的repo(你不会推legacy
,因为它的历史将被完全重写!)我只是想知道它是否有效,所以......让我们测试一下这种方法
(Git1.6.5.1,在旧的XP SP2上,由于Start-Transcript
command而带有Powershell 1.0会话)
bug10
我喜欢我不再拥有git repo目录,然后输入PS D:\> mkdir git
PS D:\> cd git
PS D:\git> mkdir tests
PS D:\git> cd tests
PS D:\git\tests> git init mainRepo
! Since 1.6.5
“
git init
”在给定额外参数(即“git init
”)时向mkdir
/chdir
学习到目录。
这太棒了!
让我们创建3个文件,用于3种不同的目的 (为了举例,我将保持每个分支的文件修改:在合并或rebase期间没有冲突。)
git init this
此时,PS D:\git\tests> cd mainRepo
PS D:\git\tests\mainRepo> echo mainFile > mainFile.txt
PS D:\git\tests\mainRepo> echo contentToBeFixed > toBeFixedFile.txt
PS D:\git\tests\mainRepo> echo legacyContent > legacy.txt
PS D:\git\tests\mainRepo> git add -A
PS D:\git\tests\mainRepo> git ci -m "first commit"
PS D:\git\tests\mainRepo> echo firstMainEvol >> mainFile.txt
PS D:\git\tests\mainRepo> git ci -a -m "first evol, for making 1.0"
PS D:\git\tests\mainRepo> git tag -m "1.0 legacy content" 1.0
返回:
git log --graph --oneline --branches
让我们构建一个* b68c1f5 first evol, for making 1.0
* 93f9f7c first commit
分支
legacy
我们回到master,再做一次提交,我们将标记为“2.0”(一个需要修复错误的版本!)
PS D:\git\tests\mainRepo> git co -b legacy
PS D:\git\tests\mainRepo> echo aFirstLegacyEvol >> legacy.txt
PS D:\git\tests\mainRepo> git ci -a -m "a first legacy evolution"
我们有:
PS D:\git\tests\mainRepo> git co -b master
PS D:\git\tests\mainRepo> git co master
PS D:\git\tests\mainRepo> echo aMainEvol >> mainFile.txt
PS D:\git\tests\mainRepo> git ci -a -m "a main evol"
PS D:\git\tests\mainRepo> echo aSecondMainEvolFor2.0 >> mainFile.txt
PS D:\git\tests\mainRepo> git ci -a -m "a second evol for 2.0"
PS D:\git\tests\mainRepo> git tag -m "main 2.0 before bugfix" 2.0
现在我们做了* e727105 a second evol for 2.0
* 473d44e a main evol
| * dbcc7aa a first legacy evolution
|/
* b68c1f5 first evol, for making 1.0
* 93f9f7c first commit
错误修复分支:
bug10
让我们在主分支上添加最终提交
PS D:\git\tests\mainRepo> git co -b bug10
PS D:\git\tests\mainRepo> echo aFirstBug10Fix >> toBeFixedFile.txt
PS D:\git\tests\mainRepo> git ci -a -m "a first bug10 fix"
PS D:\git\tests\mainRepo> echo aSecondBug10Fix >> toBeFixedFile.txt
PS D:\git\tests\mainRepo> git ci -a -m "a second bug10 fix"
主要回购的最终状态:
PS D:\git\tests\mainRepo> git co master
PS D:\git\tests\mainRepo> echo anotherMainEvol >> mainFile.txt
PS D:\git\tests\mainRepo> git ci -a -m "another main evol"
在这个阶段,我不会在mainRepo中进行任何进一步的操作。我只会克隆它进行一些测试。如果那些失败,我总是可以回到这个仓库并再次克隆它。
第一个克隆实际上是强制性的,以便执行我们的* 55aac85 another main evol
| * 47e6ee1 a second bug10 fix
| * 8183707 a first bug10 fix
|/
* e727105 a second evol for 2.0
* 473d44e a main evol
| * dbcc7aa a first legacy evolution
|/
* b68c1f5 first evol, for making 1.0
* 93f9f7c first commit
git rebase --onto
我们需要克隆仓库中的两个mainRepo分支:
PS D:\git\tests\mainRepo> cd ..
PS D:\git\tests> git clone mainRepo rebaseRepo
PS D:\git\tests> cd rebaseRepo
让我们只修改bug10(这是PS D:\git\tests\rebaseRepo> git co -b bug10 origin/bug10
PS D:\git\tests\rebaseRepo> git co -b legacy origin/legacy
之后提交2.0
HEAD
分支的所有提交:
bug10
此时PS D:\git\tests\rebaseRepo> git co bug10
PS D:\git\tests\rebaseRepo> git rebase --onto legacy 2.0
First, rewinding head to replay your work on top of it...
Applying: a first bug10 fix
Applying: a second bug10 fix
已在bug10
之上重播,没有所有其他中间提交。
我们现在可以将legacy
的{{1}}快进到重播的HEAD
分支的顶部。
legacy
内容遵循我们的需要:
bug10
PS D:\git\tests\rebaseRepo> git co legacy
Switched to branch 'legacy'
PS D:\git\tests\rebaseRepo> git merge bug10
Updating dbcc7aa..cf02bfc
Fast forward
toBeFixedFile.txt | Bin 38 -> 104 bytes
1 files changed, 0 insertions(+), 0 deletions(-)
分支的内容最多只有PS D:\git\tests\rebaseRepo> type legacy.txt
legacyContent
aFirstLegacyEvol
标记(main
分支的根目录),不再进一步。
1.0
legacy
修正在这里:
PS D:\git\tests\rebaseRepo> type mainFile.txt
mainFile
firstMainEvol
就是这样。
我们的想法是在您的原始仓库中提取“增强型”bug10
分支,该分支仍然会保持PS D:\git\tests\rebaseRepo> type toBeFixedFile.txt
contentToBeFixed
aFirstBug10Fix
aSecondBug10Fix
不变(即仍然从legacy
标记开始,并且不会在任何地方重播我们在bug10
上做了
在这个克隆的仓库中,我跟踪2.0
分支,以便在其上合并另一个远程源的rebaseRepo
分支:origin/legacy
。
legacy
在这个原始的回购中(我只是将其克隆到不干扰mainRepo的状态,如果我还有其他一些实验要做),我会将rebaseRepo
声明为远程,并获取其分支。
PS D:\git\tests\rebaseRepo> cd ..
PS D:\git\tests> git clone mainRepo finalRepo
PS D:\git\tests> cd finalRepo
PS D:\git\tests\finalRepo> git co -b legacy origin/legacy
我们现在可以更新rebaseRepo
,而无需触及PS D:\git\tests\finalRepo> git remote add rebasedRepo D:/git/tests/rebaseRepo
PS D:\git\tests\finalRepo> type D:\git\tests\finalRepo\.git\config
[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
url = D:/git/tests/mainRepo
[branch "master"]
remote = origin
merge = refs/heads/master
[branch "legacy"]
remote = origin
merge = refs/heads/legacy
[remote "rebasedRepo"]
url = D:/git/tests/rebaseRepo
fetch = +refs/heads/*:refs/remotes/rebasedRepo/*
PS D:\git\tests\finalRepo> git fetch rebasedRepo
remote: Counting objects: 8, done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 6 (delta 3), reused 0 (delta 0)
Unpacking objects: 100% (6/6), done.
From D:/git/tests/rebaseRepo
* [new branch] bug10 -> rebasedRepo/bug10
* [new branch] legacy -> rebasedRepo/legacy
* [new branch] master -> rebasedRepo/master
:
legacy
每当需要在旧的bug10
分支上重播新的PS D:\git\tests\finalRepo> git merge rebasedRepo/legacy
Updating dbcc7aa..4919b68
Fast forward
toBeFixedFile.txt | Bin 38 -> 104 bytes
1 files changed, 0 insertions(+), 0 deletions(-)
提交时,您可以根据需要重复该过程,而不包括所有中间提交。
答案 1 :(得分:2)
这很难做到。 Git保存合并历史记录,如果你“cherrypick”并指向bug10101010中的提交作为父级(表明你已完成合并),Git将假定所有提交之前(返回到他们拆分的点)合并为好。当你想进行“真正的”合并时给你带来麻烦。
另一方面,您可以从该(并且仅限于)特定提交手动生成补丁。但是,当您稍后进行“真正的”合并时,这也会给您带来问题,因为它会尝试两次应用您手动处理的提交。
但话又说回来,因为一个分支被命名为“Legacy”,我怀疑你不打算做那个真正的合并,无论如何你都可以自由地做这件事。
答案 2 :(得分:1)