代码之家  ›  专栏  ›  技术社区  ›  asmeurer

git合并:对移动到不同文件的代码应用更改

git
  •  104
  • asmeurer  · 技术社区  · 14 年前

    git merge my_branch his_branch ,git没有注意到新文件中的代码与旧文件中的代码相同,因此我所做的任何更改都不存在。

    git log --stat ). 但据我所知,没有办法让git将更改重新应用到新文件中。我现在看到的最简单的事情是手动重新应用更改,这看起来不是一个好主意。

    我知道git识别的是blob,而不是文件,所以肯定有办法告诉它,“从这个提交中应用这个精确的代码更改,除了它不在原来的位置,而是它现在在这个新文件中的位置”。

    3 回复  |  直到 14 年前
        1
  •  147
  •   Michael come lately PhiLho    4 年前

    说你修改了 original.txt 在你的树枝上 local original.txt 已经复制到另一个了,比如说 copy.txt 此副本已在我们命名为commit的commit中完成 CP .

    A B 下面是在 original.txt ,添加到新文件 copy.txt .

     ---- X -----CP------ (master)
           \ 
            `--A---B--- (local)
     
    

    move 在你改变的起点 git branch move X . 也就是说,把 提交时分支 X @迪戈里·杜 git merge-base master local 寻找 .

     ---- X (move)-----CP----- (master)
           \ 
            `--A---B--- (local)
     
    

    git mv original.txt copy.txt
    

    这将重命名文件。请注意 此时还不存在于树中。
    MV ).

            ,--MV (move)
           /
     ---- X -----CP----- (master)
           \ 
            `--A---B--- (local)
     
    

    现在,您可以在 :

    git rebase move local
    

    这应该可以毫无问题地工作,并且您的更改将应用于 copy.txt 在你当地的分公司。

            ,--MV (move)---A'---B'--- (local)
           /
     ---- X -----CP----- (master)
     
    

    现在,你不一定想要或需要承诺 毫伏 人物配对关系 在主要分支中。

    您只需重新调整工作基准,放弃移动操作,如下所示:

    git rebase move local --onto CP
    

    承诺在哪里 copy.txt 在另一个分支引入了。 这将使所有的更改重新调整 在屋顶上 人物配对关系 而不是 original.txt

                    ,--A''---B''-- (local)
                   /
     -----X-------CP----- (master)
     
    

    人物配对关系 或者别的 将不存在,并且更改将重新应用 original.txt .

    希望这是清楚的。 这个答案来得晚,但这可能对其他人有用。

        2
  •  31
  •   Cascabel    14 年前

    你可以随时使用 git diff (或 git format-patch )要生成修补程序,请手动编辑修补程序中的文件名,并使用 git apply git am ).

    除此之外,它将自动工作的唯一方法是,git的重命名检测是否能够发现旧文件和新文件是同一件事——听起来它们在您的情况下并不是真的,只是其中的一大块。git确实使用blob,而不是文件,但是blob只是整个文件的内容,没有附加文件名和元数据。因此,如果有一块代码在两个文件之间移动,它们实际上不是同一个blob—blob的其余内容不同,只是相同的块。

        3
  •  30
  •   Vincent Scheib    11 年前

    这是一个 合并 解决遇到与重命名和编辑合并冲突的方法,并使用mergetool识别正确的3个合并源文件来解决。

      1. 中止合并。
      2. 再次合并。

    走查:

    $ git init
    Initialized empty Git repository in /tmp/git-rename-and-modify-test/.git/
    
    $ echo "A file." > file.txt
    $ git add file.txt
    $ git commit -am "file.txt added."
    [master (root-commit) 401b10d] file.txt added.
     1 file changed, 1 insertion(+)
     create mode 100644 file.txt
    

    创建一个分支,稍后在其中进行编辑:

    $ git branch branch-with-edits
    Branch branch-with-edits set up to track local branch master.
    

    在主控形状上创建重命名和编辑:

    $ git mv file.txt renamed-and-edited.txt
    $ echo "edits on master" >> renamed-and-edited.txt 
    $ git commit -am "file.txt + edits -> renamed-and-edited.txt."
    [master def790f] file.txt + edits -> renamed-and-edited.txt.
     2 files changed, 2 insertions(+), 1 deletion(-)
     delete mode 100644 file.txt
     create mode 100644 renamed-and-edited.txt
    

    交换到分支,并在那里编辑:

    $ git checkout branch-with-edits 
    Switched to branch 'branch-with-edits'
    Your branch is behind 'master' by 1 commit, and can be fast-forwarded.
      (use "git pull" to update your local branch)
    $ 
    $ echo "edits on branch" >> file.txt 
    $ git commit -am "file.txt edited on branch."
    [branch-with-edits 2c4760e] file.txt edited on branch.
     1 file changed, 1 insertion(+)
    

    尝试合并主机:

    $ git merge master
    CONFLICT (modify/delete): file.txt deleted in master and modified in HEAD. Version HEAD of file.txt left in tree.
    Automatic merge failed; fix conflicts and then commit the result.
    

    $ git merge --abort
    $ git mv file.txt renamed-and-edited.txt
    $ git commit -am "Preparing for merge; Human noticed renames files were edited."
    [branch-with-edits ca506da] Preparing for merge; Human noticed renames files were edited.
     1 file changed, 0 insertions(+), 0 deletions(-)
     rename file.txt => renamed-and-edited.txt (100%)
    

    $ git merge master
    Auto-merging renamed-and-edited.txt
    CONFLICT (add/add): Merge conflict in renamed-and-edited.txt
    Recorded preimage for 'renamed-and-edited.txt'
    Automatic merge failed; fix conflicts and then commit the result.
    

    $ git mergetool
    Merging:
    renamed-and-edited.txt
    
    Normal merge conflict for 'renamed-and-edited.txt':
      {local}: created file
      {remote}: created file
    $ git commit 
    Recorded resolution for 'renamed-and-edited.txt'.
    [branch-with-edits 2264483] Merge branch 'master' into branch-with-edits
    
        4
  •  1
  •   Ernesto Baschny    4 年前

    我对这个问题的快速解决方案(在我的例子中,它不是一个文件,而是一个完整的目录结构)是:

    • git commit -m "moved to original location for merging"
    • git merge his_branch (这次没有冲突!)
    • git commit -m "moved back to final location after merge"

    您将在历史记录中有两个额外的提交。

    但是由于git跟踪文件的移动, git blame , git log etc仍将处理这些文件,因为移动这些文件的提交没有更改它们。所以我不认为这种方法有任何缺点,而且理解起来非常简单。