git合并两个提交

时间:2016-04-19 10:02:06

标签: git merge

我不确定这是否重复,我不是git专家,所以请原谅我看似愚蠢的问题。

我有一个档案。我编辑了它,保存并提交了这些更改。

我忘了我已经完成了这个并且编辑了文件的原始版本(碰巧在另一个编辑器窗口中打开),保存并提交了一组不同的更改。

因此我连续两次提交 我想生成一个<script> $(document).ready(function() { $("#input_1_38").on("propertychange change keyup", function() { var val = $("#input_1_38").val(); if (val > 6575) { $("#choice_1_49_0").prop("checked", false); $("#choice_1_49_1").prop("checked", true); } else { $("#choice_1_49_0").prop("checked", true); $("#choice_1_49_1").prop("checked", false); } }); }); </script> 样式文件,其中包含两者之间的冲突,以便我可以编辑然后解决冲突。

Git假设它可以使用所有较新的文本并丢弃旧文本 我尝试过git mergegit merge的组合,但无法确定要做什么。

我也不确定要使用哪些搜索字词。

更新

为了清楚起见,我最终想要的是一个文件中有git merge -no-ff个冲突。我可以使用git merge轻松查看两个文件之间的差异,但是输出不容易编辑。我认为git可能有一个简单的方法来说“这两个提交以这种方式冲突......”因为它必须能够在某种程度上做到这一点。

5 个答案:

答案 0 :(得分:2)

如果您只是尝试合并两个提交,那么Git将(正确地)识别出一个基于另一个并且不会最终为它创建冲突。毕竟,对于Git来说,历史看起来像这样:

                   master
                     ↓
* ---- X ---- A ---- B

B是一项更改A更改内容的提交。从版本B查看文件状态时,Git无法知道您创建了X

所以你必须改变这个事实,所以Git会使用X作为AB的基础。所以让我们先为基地创建一个分支:

git branch base X

结果如下:

      base         master
       ↓             ↓
* ---- X ---- A ---- B

现在,我们切换到base并从B签出文件并提交更改(这实际上是从B复制文件的状态)

git checkout base
git checkout master -- file.ext
git add file.ext
git commit
                   master
                     ↓
* ---- X ---- A ---- B
        \
         \
          C
          ↑
         base

现在您可以合并A并根据需要产生冲突:

git merge A

解决冲突后,结果如下:

                   master
                     ↓
* ---- X ---- A ---- B
        \      \
         \      \
          C ---- M
                 ↑
                base

此时,您具有文件所需的状态。您现在有三个选择:

  1. base合并到master以保留我们人工创建的整个历史记录。对于文件的冲突(您将在此处收到),您可以使用theirs策略来保持已解决方案的状态。
  2. 复制文件内容,切换到master,然后在B之后使用合并的内容进行新的提交。
  3. master重置为M(丢弃B),然后使用此新创建的历史记录继续。当然,这会删除提交B,因此它基本上会删除历史记录(如rebase),如果您已发布B,则应该避免使用。
  4. 由于您只是尝试合并单个文件,因此您可能最好只创建每个状态的副本,并手动合并(或使用某些合并toool)。

答案 1 :(得分:0)

如果你相互提交了两次提交,并且git没有抱怨任何事情,那就意味着你没有冲突。

我建议你

  • 软重置第二次提交
  • 针对第一次提交的差异以查看第二次提交引入的更改
  • 根据您的需要保留/放弃更改并 // \FOS\UserBundle\Form\Type\RegistrationFormType.php $builder ->add('roles', CollectionType::class, array( 'entry_type' => TextType::class, 'entry_options' => array( '/* CHOICES */' => array( /*List of Roles from security.yml*/ ) ) ); / add他们
  • 修改第1次提交。

这样,您最终会得到一个包含您希望它包含的更改的提交。

在命令中,它就像这样

rm

答案 2 :(得分:0)

如果您只进行了提交并且没有推送更改,则可以恢复您已完成的提交,此处:

How to undo last commit(s) in Git?

您将找到如何撤消上次提交的内容:

$ git commit -m "Something terribly misguided"
$ git reset --soft HEAD~
<< edit files as necessary >>
$ git add ...
$ git commit -c ORIG_HEAD

与其他设施How do I reverse a commit in git?

的其他类似信息

如果使用git对你来说很复杂,另一种方法是:将自己置于编辑文件的分支中,将编辑后的文件复制并保存在另一个文件夹中,例如。 “/ home / your_file_here”,然后将您的分支更改为master并将编辑后的文件“/ home / your_file_here”移动到master。然后你将更新文件,你可以使用“git diff your_edited_file”检查更改。

更新文件后,您只需删除修改文件的分支,执行“git branch -d branch_to_be_removed”。其他信息:How do I delete a Git branch both locally and remotely?

所以我的建议是,不要合并你拥有的两个提交,而应该撤消其中一个提交,在这种情况下是你在master中完成的提交。如果您想了解更多关于“合并”的信息,请在此处找到真正有趣的信息:Git-Branching-Basic-Branching-and-Merging并在此处:Git-Tools-Advanced-Merging

答案 3 :(得分:0)

您有几种选择。

最简单的方法是使用2个版本的代码签出2个分支,然后合并它们

<强> How to checkout 2 branches?

  1. 使用当前分支作为最新版本。
  2. 使用旧代码检出第二个分支 Read here关于如何做的非常详细的解释。

  3. 合并2个分支。

  4. 以下是有关如何操作以及您应该看到的内容的演示(只需进行合并以查看更改)。

    在本演示中,我将检查第3次提交,然后向您展示差异。

    enter image description here

答案 4 :(得分:0)

我赞成poke's answer,因为这通常是你处理这个问题的方式。

由于在问题点之前没有提交,因此只留下git checkout --orphan技巧作为唯一的方法。这实际上是一个合理的技巧,你可能会考虑它。但是,仍然存在问题;见下文。

为了完整起见,我还要注意nisevi's answerGit-Tools-Advanced-Merging的链接包含了另一种在git中处理此问题的方法。具体来说,git套件包含命令git merge-file,它基本上是旧RCS文件合并命令的克隆。

使用git merge-file

您必须提供git merge-file三个输入文件:当前版本,公共基本版本以及要合并的“其他”版本。

您无需创建新分支或提交即可使用此分支。只需查看当前版本和以前版本。

在这种情况下,git会做的是使用一个空文件作为公共基本版本(因为这两个版本之前没有版本)。我们来看看会发生什么:

$ git show HEAD~1:file > file.v1
$ git show HEAD:file > file.v2
$ : > file.base    # or cp /dev/null, or use /dev/null directly
$ cp file.v1 file.merged && git merge-file file.merged file.base file.v2

缺陷,以及如何解决它

请注意,我merge.conflictstyle设置为diff3,因此我在此处获得了公共基本版本。

$ cat file.merged

<<<<<<< file.merged
This is a file
that has some text.
This is the
version that
I call
v2,
which was
created from
scratch in
the editor.
||||||| file.base
=======
This is a file
that has some text.
This is the
version that
I call
v1,
which was
created from
scratch in
the editor.
>>>>>>> file.v1

唉! Git将整个添加(来自空基础)视为更改的两个方面,并发现整个v1版本与整个v2版本冲突。

解决方案很简单:选择两个初始版本中的所有公共线作为公共基础。实际上实现这一点有点棘手。以下是一些提示:

$ git diff --no-index -- file.v1 file.v2
[output omitted]
$ diff file.v1 file.v2
6c6
< v1,
---
> v2,

这些表明第6行是(单个)有问题的行,所以让我们创建一个省略它的file.base

$ cp file.v1 file.base && printf '6d\nw\nq\n' | ed file.base
117
113
$ cp file.v1 file.merged && git merge-file file.merged file.base file.v2
$ cat file.merged
This is a file
that has some text.
This is the
version that
I call
<<<<<<< file.merged
v1,
||||||| file.base
=======
v2,
>>>>>>> file.v2
which was
created from
scratch in
the editor.

(注意:除了git merge-file之外,还有git merge-one-file,它允许您直接从存储库中提取文件,但它的使用没有很好地记录,git merge-file做了我们的工作需要在这里,以牺牲稍后清理为代价:即删除基础,v1,v2和合并的临时文件。当然,你可以减少一个临时文件;我使用我做的方法尽量让行动更清楚。)

P.S。:您可以通过解析(plain)diff的输出或使用python的difflib来自动创建公共库。我可能会选择后者来编写这样的工具。尝试以某种方式使用comm也很诱人,但comm需要排序的输入,这太具破坏性了。 : - )