在git的两个不同分支中合并两个同名文件
我目前在名为在git的两个不同分支中合并两个同名文件,git,git-merge,git-merge-conflict,Git,Git Merge,Git Merge Conflict,我目前在名为branch1的分支中有一个名为test1的文件,该分支是从master创建的,在名为branch2的分支中还有另一个名为test1的文件,也是从master创建的。 如果我在master中合并这两个分支,那么在这两个文件中编写的代码会发生什么情况?如果您在同一位置对这两个文件进行了更改,则会出现合并冲突 如果您没有在同一位置对两个文件进行更改,它将合并而不会出现问题(可能在另一个位置发生冲突) 您可以通过编辑冲突文件、删除提交标记、添加文件并提交来解决冲突。正确地说,您将在两个合并
branch1
的分支中有一个名为test1
的文件,该分支是从master
创建的,在名为branch2
的分支中还有另一个名为test1
的文件,也是从master
创建的。
如果我在master中合并这两个分支,那么在这两个文件中编写的代码会发生什么情况?如果您在同一位置对这两个文件进行了更改,则会出现合并冲突 如果您没有在同一位置对两个文件进行更改,它将合并而不会出现问题(可能在另一个位置发生冲突) 您可以通过编辑冲突文件、删除提交标记、添加文件并提交来解决冲突。正确地说,您将在两个合并中的一个合并冲突中获得合并冲突。您必须采取措施来处理合并冲突。怎么办由你决定。但是,值得指出的是,为什么会出现一个合并冲突,而不是两个,以及为什么会发生合并冲突 Git的合并并不是真正的分支。这是关于承诺的。Git的大部分内容实际上都是关于提交的,
Git merge
在这里也没有什么不同
让我们注意一下commit是什么,它的作用是什么。每个提交都有两个部分:其数据—保存的所有文件及其元数据的快照,或有关提交的信息
- 保存的快照非常简单:如果克隆存储库并使用
,则工作树为空(还没有任何文件的可编辑或可用副本)。然后你选择一些commit any commit any any any any并告诉Git检查这个特定的commit,也许是通过它的原始散列ID。现在你有了一个所有文件的副本,这些文件都是在谁进行了这个commit,进行了那个commit时的样子 一般来说,这就是--no checkout
或new-In-git-2.23git checkout
命令的作用:您选择一些提交,然后说从该提交中获取所有文件。它们进入您的工作树或工作树,您可以在其中看到它们并对其进行操作。您还可以将其他未经Git验证的文件放入工作树中,例如编译文件或输出或其他任何内容。这些文件保持未跟踪状态(我不会在这里详细介绍,但它们不在Git中,除非/直到您删除它们,否则它们就放在您的工作树中)git switch
- 提交中的元数据记录了诸如谁将其作为自己的姓名和电子邮件地址以及何时进行的内容。这是您在
output中看到的内容 不过,元数据有一部分是专门针对Git本身的。每个提交都有一个唯一的哈希ID,每个Git都同意:一个哈希ID用于该提交,而不用于任何其他提交。因此,很容易判断您是否有提交:您只需将其哈希ID提供给Git,您的Git要么有提交,在这种情况下,它有提交,要么您的Git没有提交,在这种情况下,您必须找到其他具有提交的Git 无论如何,每个提交都将其上一次提交或父提交的哈希ID存储为其元数据的一部分。大多数人只有一个。合并提交有点特殊,因为它们有两个父级(或更多,但大多数只有两个) 这些父提交或父合并是Git存储历史的方式。每一张快照只是一张快照,但是每一张快照也都是这样的:我以前的快照是γ*(用哈希ID填空)。对于合并,这是第一个父级。对于常规提交,它是唯一的父级(因此也是第一个父级)。因此,通过返回每个提交的第一个父级,Git可以追溯到随着时间的推移发生了什么。放置两个快照:左侧为旧快照,右侧为新快照,并进行比较。这种差异告诉你发生了什么:旧的和新的之间发生了什么变化git日志
A <-B <-C <--master
现在,让我们添加一个新分支。我们将首先使用新名称并选择提交H
。我们需要一种方法来知道我们正在使用哪个分支,因此我们将把特殊名称HEAD
附加到其中一个分支名称:
...--G--H <-- master, feature1 (HEAD)
当我们添加新的提交时,Git会自动更新分支名称以指向新的提交。哪个分支名称得到更新?一个头
连接到。其他人都呆在原地
现在所有通过H
的提交都在两个分支上,而提交I
仅在feature1
上。让我们进行另一次提交,然后创建一个选择提交的新分支feature2
,并开始使用该分支:
I--J <-- feature1
/
...--G--H <-- master, feature2 (HEAD)
现在,假设在commitI
或J
中,我们创建了一个新的文件test1
,它还没有在commitH
中。假设在commitK
或L
中,我们还创建了一个名为test1
的新文件
合并
现在,我们将把这两个功能合并到主控
,一次一个。无明显原因,1我们将使用--no ff
选项:
git checkout master
git merge --no-ff feature1
为了实现这一点
当我们git checkout master
时,我们将git指向:
master
-commitH
-标识的提交提取到我们的工作树(以及Git的索引,我们在这里不讨论);及test1
,该文件位于提交L
-有一个保存的快照文件
I--J <-- feature1
/
...--G--H <-- master, feature2 (HEAD)
I--J <-- feature1
/
...--G--H <-- master
\
K--L <-- feature2 (HEAD)
git checkout master
git merge --no-ff feature1
I--J <-- feature1
/
...--G--H <-- master (HEAD)
\
K--L <-- feature2
git diff --find-renames <hash-of-H> <hash-of-H> # what we changed on master
git diff --find-renames <hash-of-H> <hash-of-J> # what they changed on feature1
I--J <-- feature1
/ \
...--G--H------M <-- master (HEAD)
\
K--L <-- feature2
git add test1
git merge --continue
git commit
I--J <-- feature1
/ \
...--G--H------M--N <-- master (HEAD)
\ /
K-----L <-- feature2