Using git to merge two directories with common parent (but different SHA1)

前端 未结 2 447
耶瑟儿~
耶瑟儿~ 2020-12-29 17:06

In our project somebody took a copy of the code. They started a new git repository in their directory and continued their work there. Meanwhile the work on our main project

相关标签:
2条回答
  • 2020-12-29 17:25

    First, I'm going to redraw your diagram.

    A --- B --- C --- D  master
    
             E --- F --- G  copy
    

    Let's first put both of these in the same repo. There are no special steps to this, you just git fetch both into the same repository.

    Then you create a graft. Edit .git/info/grafts...

    <E-sha1> <B-sha1>
    

    Then run git filter-branch to make it permanent.

    git filter-branch --tag-name-filter cat -- --all
    

    This will create a new history, the "correct" history:

    A --- B --- C --- D  master
            \
             E --- F --- G  copy
    

    After that, you can just merge.

    Demo in action

    I created two repositories which matched the diagram, copying from commit B to make commit E.

    • E has SHA-1 3aa6b69127d20ac42746c39be3c273a9d80fb706
    • B has SHA-1 95b0fc836dbea7eaa0d043390df841d184af7cd5
    $ git init
    $ git remote add master ../gittest
    $ git remote add copy ../gittest2
    $ git fetch master
    remote: Counting objects: 12, done.
    remote: Compressing objects: 100% (7/7), done.
    remote: Total 12 (delta 2), reused 0 (delta 0)
    Unpacking objects: 100% (12/12), done.
    From ../gittest
     * [new branch]      master     -> master/master
    $ git checkout -b master master/master
    Branch master set up to track remote branch master from master.
    Already on 'master'
    $ git fetch copy
    warning: no common commits
    remote: Counting objects: 9, done.
    remote: Compressing objects: 100% (6/6), done.
    remote: Total 9 (delta 0), reused 0 (delta 0)
    Unpacking objects: 100% (9/9), done.
    From ../gittest2
     * [new branch]      master     -> copy/master
    $ git log --format=oneline copy/master | tail -n 1
    3aa6b69127d20ac42746c39be3c273a9d80fb706 E
    $ git log --format=oneline master/master
    1532332fe705931babe9db04c8d84051867b52c9 D
    90903c0ac8dc26649b875ee00ea39bfd7571b1fb C
    95b0fc836dbea7eaa0d043390df841d184af7cd5 B
    e9de90c82a32041cff3a19f8e40d4358bc4ec2ca Commit A
    $ git log --format=oneline master/master
    bec0e7af9374e4c57cb87f3fd5b2fb2b6a3f431b G
    a61e01d096e81c36bcc450afd98ca94cff909622 F
    3aa6b69127d20ac42746c39be3c273a9d80fb706 E
    

    What happens if you merge now?

    I got merge conflicts that I'd rather auto-resolve.

    $ git merge copy/master
    Auto-merging test.txt
    CONFLICT (add/add): Merge conflict in test.txt
    Automatic merge failed; fix conflicts and then commit the result.
    

    Grafts in action

    $ echo 3aa6b69127d20ac42746c39be3c273a9d80fb706 \
        95b0fc836dbea7eaa0d043390df841d184af7cd5 > .git/info/grafts
    $ git filter-branch --tag-name-filter cat -- --all
    Rewrite bec0e7af9374e4c57cb87f3fd5b2fb2b6a3f431b (7/7)
    WARNING: Ref 'refs/heads/master' is unchanged
    Ref 'refs/remotes/copy/master' was rewritten
    WARNING: Ref 'refs/remotes/master/master' is unchanged
    $ git merge copy/master
    Auto-merging test.txt
    Merge made by the 'recursive' strategy.
     test.txt |    5 +++++
     1 file changed, 5 insertions(+)
    

    The final result

    $ git log --graph --oneline | cat
    *   4dadb0a Merge remote-tracking branch 'copy/master'
    |\  
    | * bb2fc85 G
    | * be88bc5 F
    | * 0816baf E
    * | 1532332 D
    * | 90903c0 C
    |/  
    * 95b0fc8 B
    * e9de90c Commit A
    
    0 讨论(0)
  • 2020-12-29 17:33

    Assume you are now in the repo include A---B---C---D.

    You need first to add the other repo into this repo use the command.

    $git remote add another_repo <git repo path>
    $git fetch another_repo
    

    Then you can merge, use

    $git merge another_repo/master
    
    0 讨论(0)
提交回复
热议问题