简体   繁体   English

有没有办法合并两个分支而不会丢失文件和更改?

[英]Is there a way to merge two branches without losing files and changes?

is there a way to merge two branches without losing files and changes? 有没有办法合并两个分支而不会丢失文件和更改?

I have this situation: 我有这种情况:
Branch A contains: 分支A包含:

  • file A (different from file A from branch B) 文件A (与分支B中的文件A不同)
  • file B (different from file B from branch B) 文件B (与分支B的文件B不同)

Branch B contains: 分支B包含:

  • file A 档案A.
  • file B 文件B.
  • file C 文件C.

Now I want to merge the branch A to branch B, the problem is that when I try to do that all changes from branch B are ignored, even the file C is deleted. 现在我想将分支A合并到分支B,问题是当我尝试这样做时,忽略来自分支B的所有更改,甚至删除文件C. How can I do that without losing changes from branch A and also from branch B? 如何在不丢失分支A和分支B的更改的情况下执行此操作? Because git didn't show me any conflicts between these files. 因为git没有向我显示这些文件之间的任何冲突。

You can do the merge by checking out branch B and having no working changes, then run the following command git merge A . 您可以通过签出分支B并且没有工作更改来执行合并,然后运行以下命令git merge A

The result will likely require a manual editing of the files to resolve conflicts before doing the final commit. 结果可能需要手动编辑文件以在执行最终提交之前解决冲突。 The following output when initiating the merge would indicate need for a manual merge. 启动合并时的以下输出表示需要手动合并。

CONFLICT (content): Merge conflict in [file A] or in file B. Or both. CONFLICT (content): Merge conflict in [file A]或文件B或两者中的CONFLICT (content): Merge conflict in [file A]

Fix the conflicts manually, then do a git add [file A] to continue on with the merge. 手动修复冲突,然后执行git add [file A]继续合并。 When all code conflicts are resolved and the code is compiling do a git commit to complete the merge commit into branch B. 解决所有代码冲突并编译代码时,执行git commit以完成合并提交到分支B.

Your fundamental error here lies in thinking that git merge has two inputs—your branch and some other branch. 你的根本错误在于认为git merge两个输入 - 你的分支和一些其他分支。 This is not the case: it has three inputs, none of which is a branch . 情况并非如此:它有三个输入,其中没有一个是分支 The three inputs are commits . 三个输入是提交

Let's draw some commits, and the branch names that remember the last commit that goes in each branch: 让我们绘制一些提交,以及记住每个分支中最后一次提交的分支名称:

          o--o--A   <-- branch-A
         /
...--o--*
         \
          o--o--B   <-- branch-B

If you run git checkout branch-A , what you get is commit A , because the name branch-A points to that particular commit. 如果你运行git checkout branch-A ,你得到的是提交 A ,因为名称branch-A指向该特定提交。 The same holds for git checkout branch-B . git checkout branch-B Comparing these two commits shows some difference(s) in some file(s). 比较这两个提交在某些文件中显示了一些差异。 That does matter, but not all that much . 这很重要,但并不是那么重要

From commit A , we can work backwards (as git log would) to an unnamed commit, then another unnamed commit, then commit * . 从提交A ,我们可以向后工作(如git log )到未命名的提交,然后是另一个未命名的提交,然后提交* From B , we can do the same thing, and if we do we arrive also at commit * . B ,我们可以做同样的事情,如果我们这样做,我们也到达提交* So commit * —the merge base of the proposed merge operation—is the best common commit , the best commit that's on both branches. 因此,提交* - 建议的合并操作的合并基础 - 是最好的常见提交 ,是两个分支上的最佳提交。

The way merge works is to run two git diff s: 合并的方式是运行两个 git diff

  • The first compares the snapshot in commit * to that in commit A , to see what someone changed on that path. 第一个将commit *的快照与提交A的快照进行比较,以查看某个人在该路径上的更改。
  • The second compares the snapshot in commit * to that in commit B , to see what someone changed on that path. 第二个将commit *的快照与提交B的快照进行比较,以查看某个人在该路径上的更改。

Then Git combines these two sets of changes. 然后Git 结合了这两组变化。 The resulting combined changes, if they have no conflicts, get applied to the snapshot from commit * . 如果没有冲突,则生成的组合更改将从commit *应用于快照。

Having combined the two sets of changes and applied them correctly—or as correctly as Git can determine—Git goes on to make a new commit, mostly in the usual way. 结合了两组更改并正确应用它们 - 或者正确,因为Git可以确定 - Git继续进行新的提交,主要是以通常的方式。 The new commit causes whichever branch you have checked out (one of the two branch-A or branch-B names) to get updated to point to the new commit. 新提交会导致您检出的分支(两个分支A或分支B名称之一)更新为指向新提交。 The new commit has two parents, which are commits A and B . 新提交有两个父项,即提交AB So the end result is: 所以最终的结果是:

          o--o--A
         /       \
...--o--*         M   <-- branch-<whichever> (HEAD)
         \       /
          o--o--B

with whichever branch name didn't move, still pointing to either A or B . 无论哪个分支名称都没有移动,仍然指向AB

The snapshot in new merge commit M is that from * , plus both sets of changes . 新合并提交M快照是来自* ,以及两组更改 If A didn't change something from * , but B did change something from * , you get B 's changes. 如果A没有从*改变某些东西,但是B确实从*改变了某些东西,那么你得到了B的改变。 If A did change something and B didn't, you get A 's changes. 如果A确实改变了某些东西而B没有改变,那么你会得到A的改变。 If both changed the same lines of the same file, then you get a merge conflict—and you have to finish the merge job and make M yourself. 如果两个更改同一文件的同一行, 那么你得到一个合并冲突,你必须完成合并作业,使M自己。

(If file C is in one of A and B , but not in the other, file C must either have been created-since- * or removed-since- * . Merge combines create new file with nothing by taking the new file. It combines remove old files with nothing by removing the old file. Given your text description, C must exit in * , giving you the remove file action.) (如果文件CAB ,但在另一个中,则文件C必须已经创建 - 自 - *或者删除 - 自 - * 。合并通过获取新文件将创建新文件任何内容组合在一起。结合通过删除旧文件删除任何 旧文件 。鉴于你的文字说明, C必须退出* ,给你删除文件的操作。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM