【问题标题】:How do I merge changes to a single file, rather than merging commits?如何将更改合并到单个文件,而不是合并提交?
【发布时间】:2012-06-02 19:31:15
【问题描述】:

我有两个分支(A 和 B),我想将来自分支 A 的单个文件与来自分支 B 的相应单个文件合并。

【问题讨论】:

标签: git merge git-branch


【解决方案1】:

这使用了 git 的内部 difftool。 也许有一点工作要做,但直截了当。

#First checkout the branch you want to merge into
git checkout <branch_to_merge_into>
    
#Then checkout the file from the branch you want to merge from
git checkout <branch_to_merge_from> -- <file> 
    
#Then you have to unstage that file to be able to use difftool
git reset HEAD <file> 

#Now use difftool to chose which lines to keep. Click on the mergebutton in difftool
git difftool

#Save the file in difftool and you should be done.

【讨论】:

  • 为了阐明--(空参数标签)的使用,git checkout 文档:ARGUMENT DISAMBIGUATION 说:“如果你想从索引中检出这些路径,请使用git checkout -- &lt;pathspec&gt;。”这是因为您可以同时拥有同名的分支和文件/路径。在这种情况下,git 不会要求您明确是否应该在分支或路径都存在时签出,而是默认选择签出分支。但是,如果 -- 之前 git 将检查文件/路径。
  • git diff 也可以用来验证差异。
【解决方案2】:
git checkout <target_branch>
git checkout <source_branch> <file_path>

【讨论】:

【解决方案3】:

我会这样做

git format-patch branch_old..branch_new file

这将为文件生成一个补丁。

在目标分支旧处应用补丁

git am blahblah.patch

【讨论】:

  • 您能否轻松查看补丁以提高安全性?
  • 不确定我做错了什么,但我无法让 git 生成补丁文件。虽然没有报告错误
【解决方案4】:

我发现这种方法简单实用:How to "merge" specific files from another branch

事实证明,我们太努力了。我们的好朋友 git checkout 是适合这项工作的工具。

git checkout source_branch &lt;paths&gt;...

我们可以简单地为 git checkout 提供功能分支 A 的名称以及我们要添加到主分支的特定文件的路径。

请阅读整篇文章以获得更多理解

【讨论】:

  • 这会覆盖文件,但不会合并它们
  • 对你来说可能,这取决于你在做什么以及你想要实现什么。这里的想法是分支 B 是 A 的分支,您在 B 中修改了 4 个文件,但只想将 2 个从 B 合并到 A。常规合并将合并所有 4 个,您可以在这里选择。这可能看起来像是被覆盖了,因为 B 包含本质上较新的文件。你需要用一些证据来支持你的经历。
  • 我同意它会覆盖。我认为您的意思是在该命令中使用 -p 选项。然后,不幸的是,在补丁更改之前,它会覆盖您工作树文件中先前从您签出的分支转移的任何部分。
  • 这个想法是从 2009 年开始的,很可能新版本的 git 行为不同并且需要 -p 或其他任何东西,但是当我发布它时它对我有用,但也许我没有关心被覆盖的文件,因为我需要最新版本
  • 覆盖,你不关心吗?绝对误导,投反对票。
【解决方案5】:

您可以签出要合并的文件的旧版本,将其保存为不同的名称,然后在这两个文件上运行您的合并工具。

例如。

git show B:src/common/store.ts &gt; /tmp/store.ts(其中 B 是分支名称/提交/标签)

meld src/common/store.ts /tmp/store.ts

【讨论】:

    【解决方案6】:

    我遇到了同样的问题。准确地说,我有两个分支AB,它们的文件相同,但某些文件中的编程接口不同。现在,文件f 的方法与两个分支的接口差异无关,在分支B 中进行了更改,但更改对两个分支都很重要。因此,我只需要将分支B 的文件f 合并到分支A 的文件f 中。

    如果我假设所有更改都在AB 两个分支中提交,那么一个简单的命令已经为我解决了这个问题:

    git checkout A
    
    git checkout --patch B f
    

    第一个命令切换到分支A,我想要合并B 的文件f 的版本。第二个命令用fHEADB 修补文件f。您甚至可以接受/丢弃补丁的单个部分。你可以在这里指定任何提交,而不是B,它不必是HEAD

    社区编辑:如果B 上的文件fA 上尚不存在,则省略--patch 选项。否则,您将得到“无变化”。消息。

    【讨论】:

    • 这仅在您想要更新文件时有效。如果我想将新文件从分支 B 添加到分支 A 怎么办?
    • @UmairAshraf 您应该能够通过删除 --patch 选项将新文件从 B 添加到 A。
    • 嗯......当我尝试这个时,我收到“没有变化”的消息,但显然有变化。好的,我需要在相关文件所在的文件夹中。编辑:这很可能是我在stackoverflow上看到的问题最喜欢的解决方案:-D
    • 我必须使用 git checkout --patch B -- f 才能让它工作。
    • 只需补充一点,如果您在文件中有多个更改(大块)并且您希望暂存所有更改,您可以按a 在交互阶段,而不是每次都按 y。或者改用git checkout B -- f 命令。
    【解决方案7】:

    以下命令将 (1)比较正确分支的文件,掌握 (2) 以交互方式询问您要应用哪些修改。

    git checkout --patch master

    【讨论】:

    • 我想你的意思是git checkout --patch master &lt;filespec&gt;
    【解决方案8】:

    假设 B 是当前分支:

    $ git diff A <file-path> > patch.tmp
    $ git apply patch.tmp -R
    

    请注意,这只会将更改应用于本地文件。之后您需要提交。

    【讨论】:

    • 对我来说,这会生成一个error: &lt;file-path&gt;: already exists in working directory
    • 您应该在当前目录中指定文件或文件路径。我正在使用git diff Branch_A &lt;file-path, filename&gt; -- hash_commit &gt; file_name.temp
    【解决方案9】:

    【讨论】:

    • 我试图只合并一个文件,但来自另一个分支。我没有看到从另一个分支合并的选项git merge-file
    【解决方案10】:

    我的编辑被拒绝了,所以我在此处附上了如何处理来自远程分支的合并更改。

    如果在不正确的合并后必须这样做,你可以这样做:

    # If you did a git pull and it broke something, do this first
    # Find the one before the merge, copy the SHA1
    git reflog
    git reset --hard <sha1>
    
    # Get remote updates but DONT auto merge it
    git fetch github 
    
    # Checkout to your mainline so your branch is correct.
    git checkout develop 
    
    # Make a new branch where you'll be applying matches
    git checkout -b manual-merge-github-develop
    
    # Apply your patches
    git checkout --patch github/develop path/to/file
    ...
    
    # Merge changes back in
    git checkout develop
    git merge manual-merge-github-develop # optionally add --no-ff
    
    # You'll probably have to
    git push -f # make sure you know what you're doing.
    

    【讨论】:

      【解决方案11】:

      这是我在这些情况下所做的。这是一个杂物,但对我来说效果很好。

      1. 根据您的工作分支创建另一个分支。
      2. git pull/git 合并包含您要复制的文件的修订版 (SHA1)。因此,这将合并您的所有更改,但我们仅使用此分支来获取一个文件。
      3. 修复任何冲突等。调查您的文件。
      4. 检查您的工作分支
      5. 签出从合并中提交的文件。
      6. 提交。

      我尝试打补丁,但我的情况太糟糕了。所以简而言之,它看起来像这样:

      工作分支:A 实验分支:B(包含 file.txt,其中包含我想要折叠的更改。)

      git checkout A
      

      基于A创建新分支:

      git checkout -b tempAB
      

      将 B 合并到 tempAB 中

      git merge B
      

      复制合并的sha1哈希:

      git log
      
      commit 8dad944210dfb901695975886737dc35614fa94e
      Merge: ea3aec1 0f76e61
      Author: matthewe <matthewe@matthewe.com>
      Date:   Wed Oct 3 15:13:24 2012 -0700
      
      Merge branch 'B' into tempAB
      

      检查您的工作分支:

      git checkout A
      

      检查您的固定文件:

      git checkout 7e65b5a52e5f8b1979d75dffbbe4f7ee7dad5017 file.txt
      

      你应该拥有它。提交你的结果。

      【讨论】:

      • 所以我们必须做这一切只是为了合并一个文件?将文件复制并粘贴到另一个分支中会不会更容易
      • @Robin 可能不会,因为合并会保留文件上的更改,这些更改在分支 A 和 B 之间有所不同。复制文件将覆盖您的工作分支 A 与您想要带来的任何其他差异来自 B,其中可能不包含这些条目/编辑。例如怀疑A 以其他方式从B 开始转移。复制会覆盖这些差异。
      猜你喜欢
      • 2020-09-29
      • 2010-12-12
      • 1970-01-01
      • 1970-01-01
      • 2011-09-05
      • 2013-11-13
      • 1970-01-01
      • 2012-11-26
      • 1970-01-01
      相关资源
      最近更新 更多