强制合并并忽略«已更新。»

时间:2020-10-26 17:14:56

标签: git

问题

我有那个历史:

(C1) <---(C2)
     \
      \--(C3)
C1: empty commit.
C2: file1.txt
C3: file2.txt file3.txt

我想要什么:

(C1) <---(C2) <---(C4) <--(C5)
     \            /       /
      \--(C3) <--/-------/
C4: file1.txt file2.txt
C5: file1.txt file2.txt file3.txt

我尝试使用git merge来执行此操作,但是它写给我“已经是最新的。”。 我必须使用命令git cat-filegit mktreegit hash-objectgit ls-tree来完成我想做的事情。有没有更简单的方法?

如何重复

您可以重复自己的操作,并检查是否无法执行我想要的操作(Ubuntu bash):

git init /tmp/force-merge
cd /tmp/force-merge/
git commit --allow-empty -m "empty commit."
echo 1 > file1.txt
git add file1.txt
git commit -m "file1.txt"
git checkout -b develop master~1
echo 2 > file2.txt
echo 3 > file3.txt
git add file2.txt file3.txt
git commit -m "file2.txt file3.txt"
git checkout master
git merge --no-commit develop
git rm -f file3.txt
git commit -m "file1.txt file2.txt"
git merge --no-commit develop

您将获得“已经更新”。 git日志:

$ git log --oneline --graph --all
*   59f6836 (HEAD -> master) file1.txt file2.txt
|\  
| * 884b550 (develop) file2.txt file3.txt
* | 5117ae6 file1.txt
|/  
* 94dfb3b empty commit.

2 个答案:

答案 0 :(得分:0)

获取建议的提交的一种干净方法是创建一个新分支,该分支将删除file3,然后将其合并。

C1 - C2 [master]
 \
  C3 [develop]

$ git co -b develop develop-no-file3

C1 - C2 [master]
 \
  C3 [develop]
     [develop-no-file3]

$ git rm file3
$ git commit

C1 - C2 [master]
 \
  C3 [develop]
    \
     C3A [develop-no-file3]

现在,您可以根据需要合并每个对象。在不知道您的目的的情况下,我无法确切地说出应该如何合并,但是将合并置于彼此之上似乎没有多大意义。由于develop-no-file3似乎是暂时的,因此您可以将development合并为master,然后将master合并为development-no-file3。

$ git checkout develop-no-file3
$ git merge master

$ git checkout master
$ git merge develop

C1 --------- C2 ----- C3M [master]
 \             \    /
  C3  ----------*---
    \            \
     C3A -------- C3AM [develop-no-file3]

如果这样做是为了产生不同的软件配置,可能是针对不同的部署,或者是删除仅开发代码; Git不是配置管理系统。这应该用另一种方式处理。

答案 1 :(得分:0)

这将重新创建您的开始条件:

git init `mktemp -d`
cd $_
git commit --allow-empty -m C1
> file1.txt; git add .
git commit -m C2
git checkout -b topic :/C1
> file2.txt
> file3.txt; git add .
git commit -m C3

这将创建C4:

git checkout master
git merge --no-commit topic
git rm -f file3.txt
git commit -am C4

这将创建C5:

git checkout :/C3 file3.txt
git reset --soft $(git commit-tree -p @ -p topic -m C5 `git write-tree`)

通过将C3拆分为单独的提交并合并它们,您可以更加整洁地做到这一点,

git checkout -B topic :/C1
> file2.txt; git add .
git commit -m C3a
> file3.txt; git add .
git commit -m C3b
git checkout -B master :/C2
git merge :/C3a
git merge topic