2017-05-08 60 views
2

我在2个分支中工作,混淆了一切。针对分支A的一些更改在分支B中,而相反。一些提交包含更改正确的分支和错误的错误的同时。我对这个组合做了几次提交。git:混淆分支 - 如何清理

之后我再次在正确的分支中做了更改。 所以我结束了正确分支的所有更改,但每个分支也都属于另一个分支。 然后对于我推送的分支A和分支B,我已经提出了请求。

问题1:如何从每个分支中删除不属于此处的更改? 我确切地知道我需要恢复到原始状态的分支中的哪些文件。

问题2:如何更改已经发出的拉请求?

+0

是那个已经被接收器合并的请求了吗? – quetzalcoatl

+0

不,他们没有合并它 –

+0

如果他们还没有合并它,然后**拉请求**是没有意义的。基本上它只记得一个“注释”,说“请将我的公共回购分支FOOBAR合并到你的BARFOO”。当你清理一些事情然后发布/推送那些清理时,pull请求将不会改变。它**仍然会告诉相同的**:“请将我的foobar合并到您的barfoo中”。但是,现在,显然,您的foobar将在清理后=>因此,您可以认为“拉取请求”是自动自我更新。当然,它很方便,但只要它们尚未合并即可。 – quetzalcoatl

回答

1

为了将来的参考,在推送之前清理它会更安全。在这一点上,你有两个选择:

  • 您可以创建新的分支机构(新名称)和迁移所需的更改他们每个人。现有的分支将最终被放弃。

  • 您可以“重写历史记录”来修复现有分支。任何取回/拉动现有分支的人都必须执行恢复程序(请参阅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这些改变 - 你可以改变命令从pickdrop

如果任何承诺有变化的组合(有些属于上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选项)。

+0

Tkx ,,这很清楚。我们在分支中也有不止一个功能,您的解决方案我认为可以为每个功能创建一个新的分支并从RootA开始,只需选择该功能的更改即可。然后为特征2创建一个分支,从RootA开始,再次只选择属于特征2的更改。如果所有功能都拆分删除brancheA。它是否正确? –

+0

@JacJac是的,这是正确的。 –

0

如果您还没有推开这些分支的是,你可以:

  • 创建分支tmpAtmpB(例如从origin/Aorigin/B
  • git cherry-pick你需要从AtmpA的提交,和从BtmpB;如果你需要编辑提交使用选项--no-commit,然后git reset清除指数,其次是git add -p只添加需要进行修改,然后提交结果
  • 重置这些地方分行AtmpAgit branch -f A tmpA),同样为B
  • 删除tmpAtmpB
+0

Tkx,与樱桃挑选是可能分裂一个承诺?在一次提交中,我们有时会更改brancheA和nrancheB。我认为樱桃采取整个承诺? –

+0

@JacJac是的,但你可以使用'git cherry-pick'和'--no-commit'选项。然后做一个'git reset',你现在可以用'git add -p'只添加你需要的东西。一旦你添加了你需要的文件(或文件的一部分),提交并执行'git clean -fd'。 – VonC