合并同一分支上的两个GIT提交
我重新制造了一个我已经遇到过几次的问题。这是基本情况: 创建包含以下内容的文件file1.txt: 你好,合并同一分支上的两个GIT提交,git,Git,我重新制造了一个我已经遇到过几次的问题。这是基本情况: 创建包含以下内容的文件file1.txt: 你好, 欢迎来到我的档案。 再见 将第二个正文行添加到file1.txt**注意:添加此行时:“意外”删除“欢迎使用我的文件” 你好, 这是第二行。 再见 合并这两个提交的最佳方式是什么?目标是使文件file1.txt包含以下内容: 你好, 欢迎来到我的档案。 这是第二行。 再见 到目前为止,我尝试的是: $ git checkout 6d83.. $ git branch tmp $ git c
欢迎来到我的档案。
再见 将第二个正文行添加到file1.txt**注意:添加此行时:“意外”删除“欢迎使用我的文件” 你好,
这是第二行。
再见 合并这两个提交的最佳方式是什么?目标是使文件file1.txt包含以下内容: 你好,
欢迎来到我的档案。
这是第二行。
再见 到目前为止,我尝试的是:
$ git checkout 6d83..
$ git branch tmp
$ git checkout master
$ git merge tmp
但我得到的信息是“已经是最新的”。git rebase是这里最好的选择吗?为什么创建一个临时分支然后合并不起作用呢?在git中没有办法完成您想要做的事情。如果有任何问题,它将导致合并冲突。您不能像上面尝试的那样通过合并自动完成。但是,假设您已经正确配置了您最喜欢的diff编辑器,这将允许您在提交之前手动修复文件并访问以前的内容。在您的主分支上:
git difftool ccd8:file1.txt file1.txt
一旦正确修复并保存,退出编辑器后
git add file1.txt
如果尚未推送,则可以修改以前的提交
git commit --amend
或者用恢复的生产线创建一个全新的生产线
git commit -m "Recovered line"
这里的问题是,就Git而言,删除您删除的行是正确的答案 记住Git的基本存储单元是提交。每次提交都有:
- 一些数据:所有文件的快照;及
- 一些元数据:关于提交的信息。这包括谁制作的、何时(日期和时间戳)以及为什么(您或提交人的日志消息)。不过,Git最后也是最重要的元数据是父提交哈希ID
... <-F <-G <-H
现在,让我们进行新的提交,添加这个新文件,file1.txt
。提交H
根本没有file1.txt
它有一些其他文件,但没有file1.txt
。我们git add file1.txt
并运行git commit
并提供一条日志消息。Git创建了一个新的提交,它将获得一个新的唯一的大而丑陋的散列ID,但我们将其称为I
。Git将父项设置为H
,以便I
指向H
:
...--F--G--H <-- master
\
I
(没有理由将绘图I
放在单独的行中,因此我们不会这样做。)
现在,您可以编辑文件,并按照通常的过程进行新的提交J
。提交J
将I
作为其父级,Git将J
的哈希ID写入名称master
:
...--F--G--H
\
I <-- master
...--F--G--H--I--J <-- master
...--G--H <-- master (HEAD), dev
现在我们将创建一两个新分支。当我们这样做时,我们需要在绘图中再添加一件东西。如果只有一个分支名称,master
,那可能就是我们正在使用的分支。但是,如果我们添加了dev
作为第二个名称会怎么样?我们用的是哪个名字
Git对此的回答是使用特殊的名称HEAD
。此特殊名称通常附加到您的分支机构名称之一。(它只能附加到一个或无:不能超过一个。)我们将添加第二个分支名称,dev
,但将HEAD
附加到master
:
...--F--G--H
\
I <-- master
...--F--G--H--I--J <-- master
...--G--H <-- master (HEAD), dev
请注意,dev
尚未移动:它仍然指向现有的提交H
。名称master
现在指向newcommitJ
现在,让我们在dev
上创建两个提交。我们首先做git checkout dev
。这会将我们的头连接到dev
,并提取commitH
的内容,以便与/一起工作:
I--J <-- master
/
...--G--H <-- dev (HEAD)
现在我们可以运行git merge
。我们选择一个分支使用我们git checkout master
或git checkout dev
,然后运行git merge
,并给它另一个分支的名称。4让我们git checkout master
和git merge dev
,以便HEAD
和当前提交,识别J
而不是L
:5
我们合并了。合并后的快照是将H
-vs-J
和H
-vs-L
的组合更改应用于H
的结果。合并的父级是前一个提交(与往常一样),另一个是我们在运行git merge dev
时选择的提交
既然此合并已存在,则无法尝试将L
甚至K
合并到master
中。原因是L
和M
之间的最佳共享提交是提交L
。。。这已经是M
历史的一部分。如果我们沿着最下面一行从M
后退,我们将到达L
。Git中由提交(包括它们的连接)组成的历史表明,L
已经在这里合并
3当你问Git时:
头中有什么?你有两种表达方式。你可以问Git:What分支名称
I--J <-- master (HEAD)
/
...--G--H <-- dev
I--J <-- master
/
...--G--H <-- dev (HEAD)
I--J <-- master
/
...--G--H
\
K--L <-- dev (HEAD)
I--J <-- master (HEAD)
/
...--G--H
\
K--L <-- dev
I--J
/ \
...--G--H M <-- master (HEAD)
\ /
K--L <-- dev
o--P--C--o--o <-- branch1
/
...--o--o
\
o--o--H <-- branch2 (HEAD)
...--o--o--P--C--o--o--H <-- branch (HEAD)
o--P--C--o--o <-- branch1
/
...--o--o
\
o--o--H--C' <-- branch2 (HEAD)
...--o--o--P--C--o--o--H--C' <-- branch (HEAD)