在git重新基址期间解决冲突时,如何从一个分支中选择文件?

在git重新基址期间解决冲突时,如何从一个分支中选择文件?,git,Git,给定一个git回购协议,它有两个分支master和feature。当使用rebase master在master上重新设置功能分支的基址时,假设文件a.txt包含一个冲突,需要先解决该冲突,然后才能继续重新基址 我知道我可以通过三个步骤解决冲突: 在我的编辑器中打开a.txt,手动解决冲突 调用git add a.txt告诉git我已经手动解决了冲突 调用git rebase--continue向前移动rebase 有没有一种方法可以避免第1步,即告诉git我想要主分支的文件版本,或者我想要fe

给定一个git回购协议,它有两个分支
master
feature
。当使用
rebase master
在master上重新设置功能分支的基址时,假设文件
a.txt
包含一个冲突,需要先解决该冲突,然后才能继续重新基址

我知道我可以通过三个步骤解决冲突:

  • 在我的编辑器中打开
    a.txt
    ,手动解决冲突
  • 调用
    git add a.txt
    告诉git我已经手动解决了冲突
  • 调用git rebase--continue向前移动rebase

  • 有没有一种方法可以避免第1步,即告诉git我想要主分支的文件版本,或者我想要feature分支的文件版本,而不必执行上面的步骤1和步骤2。

    我相信,您正在寻找的,可以摆脱所有三个步骤的是

    git-rebase-master-X-theres

    将自动解决有利于
    功能的冲突(当前签出的分支),或

    git-rebase-master-X-ours

    我们的
    他们的
    作为重设基础的参数是违反直觉的,如

    选项说明中所述,您可以使用:

    git checkout --ours -- path/to/file
    
    或:


    …在合并或重设基础期间选择冲突文件的特定版本;因为重定基址是,
    --他们的
    在这种情况下将是
    功能的版本,
    --我们的
    将是
    主版的。

    是的。事实上,有不止一种方法可以做到这一点

    rebase和merge(以及cherry pick)命令都采用相同的
    策略
    -X
    标志传递给底层git合并机制。对于
    递归
    策略,
    -Xours
    -x其继承者
    在合并两个分支中修改文件的情况下,选择文件的一个或另一个“侧面”

    或者,这在合并因冲突而停止的情况下是完全不同的,您可以使用带有
    --ours
    --theres
    标志的
    git checkout
    ,从一方或另一方选择版本。(您可以使用其他命令执行此操作;在这里,我将继续使用
    --ours
    --theres
    ,因为它们与使用合并机制的命令的参数相匹配。)

    这当然不同,因为您可以切换选项:

    $ git checkout main
    Switched to branch 'main'
    $ git merge branch
    ... conflicts in files A and B ...
    $ git checkout --ours -- A    # takes main:A
    $ git checkout --theirs -- B  # takes branch:B
    
    请注意,这与“我们的策略”(上面显示的是带有
    ours
    选项的“
    recursive
    策略”)大不相同。在“我们的战略”下,发生了完全不同的事情。让我们从没有它开始,再次执行相同的合并:

    $ git checkout main && git merge branch
    ... conflicts ...
    $ git checkout --ours -- A B  # take main:A and main:B
    
    假设还有第三个文件,
    C
    ,git可以自己合并。当您执行上述操作时,git合并
    C
    ,您使用
    main:A
    main:B
    。但是,如果要使用
    git merge--strategy=ours分支
    ,git将采用
    main:A
    main:B
    main:C
    。它将放弃
    分支:C
    更改,而不是自动合并它们

    我在上面使用了
    git merge
    ,因为它使“我们的”和“他们的”东西“正常工作”。不过,我不喜欢git命名这些的方式,因为当你在做一个rebase时,我们/他们的版本会被交换,因为rebase的工作方式是更改为“其他”分支并进行一系列的挑选。即:

    $ git checkout mine; git rebase theirs
    
    通过做(非常)粗糙的等效工作,在下面工作:

    $ git checkout theirs; git cherry-pick theirs..mine
    

    然后,移动分支标签,使分支
    它们的
    实际上不会移动。(内部并没有那么糟糕:-)但它确实设法使
    --我们的
    表示“他们的”,而
    --他们的
    表示“我们的”,这在外部非常糟糕。)

    如果有两个冲突的文件a.txt和b.txt,我可能希望从主分支选择a.txt,而b.txt我可能希望手动合并。您建议的命令是否应用于所有冲突的文件?在这种情况下,Ash Wilson的答案是:)实际上,您不需要
    git add
    ,因为签出写入“通过索引”,在将我们或他们的版本写入工作树之前,将其复制到索引中的“插槽0”中。(尽管这样做是无害的)哦,真的吗?我想我也得把它搬上舞台,让它成为一个决议。我会更新答案的,谢谢!感谢您解释为什么rebase会在我们和他们的标签之间切换。
    $ git checkout theirs; git cherry-pick theirs..mine