我在2个分支中工作,混淆了一切。针对分支A的一些更改在分支B中,而相反。一些提交包含更改正确的分支和错误的错误的同时。我对这个组合做了几次提交。git:混淆分支 - 如何清理
之后我再次在正确的分支中做了更改。 所以我结束了正确分支的所有更改,但每个分支也都属于另一个分支。 然后对于我推送的分支A和分支B,我已经提出了请求。
问题1:如何从每个分支中删除不属于此处的更改? 我确切地知道我需要恢复到原始状态的分支中的哪些文件。
问题2:如何更改已经发出的拉请求?
我在2个分支中工作,混淆了一切。针对分支A的一些更改在分支B中,而相反。一些提交包含更改正确的分支和错误的错误的同时。我对这个组合做了几次提交。git:混淆分支 - 如何清理
之后我再次在正确的分支中做了更改。 所以我结束了正确分支的所有更改,但每个分支也都属于另一个分支。 然后对于我推送的分支A和分支B,我已经提出了请求。
问题1:如何从每个分支中删除不属于此处的更改? 我确切地知道我需要恢复到原始状态的分支中的哪些文件。
问题2:如何更改已经发出的拉请求?
为了将来的参考,在推送之前清理它会更安全。在这一点上,你有两个选择:
您可以创建新的分支机构(新名称)和迁移所需的更改他们每个人。现有的分支将最终被放弃。
您可以“重写历史记录”来修复现有分支。任何取回/拉动现有分支的人都必须执行恢复程序(请参阅git rebase
文档中的“从上游重新分配中恢复”以获得对此问题的一般性讨论)。
我会写出此过程假设第一个选项,因为它在某些方面更安全。如果您想使用历史重写,我会提供一些关于如何调整过程的说明。我将展示如何执行branchA
,并且branchB
的过程基本相同。我将假设分支是从master
创建的(因此如果不是,则用相应的“父分支”替换对master
的所有引用)。
检出现有分支。
git checkout branchA
假设你不希望新的分支将被移动到master
小费,你需要找到分支点。为了简化说明,我们在那里创建一个临时标记(尽管从技术上讲,您可以使用SHA1 ID来代替此提交)。
所以,你必须
x --- A --- x <--(master)
\
A1 --- B1 --- AB1 --- A2 <--(branchA)
,你需要找到A
。如果您知道有(在这个例子中)在branchA
4个提交后,从master
分裂,你可以说
git tag rootA branchA~4
如果你不知道电话号码,你可以从一个GUI前端它眼珠子或者从git log --graph master branchA
(如果提交历史就足够,这是实用的小),如果还是不行:
git rev-list master..branchA
输出的最后一行是SHA1为第一承诺在你的分支,所以假设这是31337c0d3你会
git tag rootA 31337c0d3^
(注意末尾的^
)。
的一种方式或其他,你现在应该有
[rootA]
|
x --- A --- x <--(master)
\
A1 --- B1 --- AB1 --- A2 <--(branchA)
现在,创建新的分支(但你可以如使用“改写历史”选项,跳过此步骤)。
git checkout -b new_branchA
现在开始交互式衍合会议
git rebase -i --onto rootA master
你会得到一个文本编辑器以“待办事项”列表中,代表提交每行。
对于上branchA
属于提交,保留线路不变(pick
命令)
对于上branchB
属于提交 - 考虑到你已经有branchB
这些改变 - 你可以改变命令从pick
到drop
如果任何承诺有变化的组合(有些属于上branchA
,也有人认为在branchB
属于),从pick
命令更改为edit
保存并退出文本编辑器,git将启动rebase。如果你用edit
标记了任何提交,那么git会暂停并提示你进行编辑,然后告诉它恢复rebase。
当底垫完成后,你将有
[rootA]
|
x --- A --- x <--(master)
|\
| A1 --- B1 --- AB1 --- A2 <--(branchA)
\
A1' --- Ab1' --- A2' <--(new_branchA)
(其中Ab1'
是AB1
编辑的更换只意味着BranchA
变化保持)。
如果您将其作为历史重写,那么branchA
将指向A2'
,当然不会有new_branchA
。
您可以清理temp标签。
git tag --delete rootA
,除非你是一个历史的改写,你不再需要的旧branchA
:
git branch --delete branchA
最后,你可以把远程
git push
(在该情况下,的历史重写,将需要-f
选项)。
Tkx ,,这很清楚。我们在分支中也有不止一个功能,您的解决方案我认为可以为每个功能创建一个新的分支并从RootA开始,只需选择该功能的更改即可。然后为特征2创建一个分支,从RootA开始,再次只选择属于特征2的更改。如果所有功能都拆分删除brancheA。它是否正确? –
@JacJac是的,这是正确的。 –
如果您还没有推开这些分支的是,你可以:
tmpA
和tmpB
(例如从origin/A
和origin/B
)git cherry-pick
你需要从A
到tmpA
的提交,和从B
到tmpB
;如果你需要编辑提交使用选项--no-commit
,然后git reset
清除指数,其次是git add -p
只添加需要进行修改,然后提交结果A
到tmpA
(git branch -f A tmpA
),同样为B
。tmpA
和tmpB
。Tkx,与樱桃挑选是可能分裂一个承诺?在一次提交中,我们有时会更改brancheA和nrancheB。我认为樱桃采取整个承诺? –
@JacJac是的,但你可以使用'git cherry-pick'和'--no-commit'选项。然后做一个'git reset',你现在可以用'git add -p'只添加你需要的东西。一旦你添加了你需要的文件(或文件的一部分),提交并执行'git clean -fd'。 – VonC
是那个已经被接收器合并的请求了吗? – quetzalcoatl
不,他们没有合并它 –
如果他们还没有合并它,然后**拉请求**是没有意义的。基本上它只记得一个“注释”,说“请将我的公共回购分支FOOBAR合并到你的BARFOO”。当你清理一些事情然后发布/推送那些清理时,pull请求将不会改变。它**仍然会告诉相同的**:“请将我的foobar合并到您的barfoo中”。但是,现在,显然,您的foobar将在清理后=>因此,您可以认为“拉取请求”是自动自我更新。当然,它很方便,但只要它们尚未合并即可。 – quetzalcoatl