简体   繁体   中英

Best practice using and merging external Git repositories

I have this internal project in our internal Git-repository A , where I had to add and adapt a major part of code from an external library from an external Git-repository B . I did not add the total history of B, I just added all the present code (let's call it B3 ) in one commit (let's call it A5_B3' ) with a commit-message explicitly referring to B3 . Then I removed everything I did not need in an additional commit and adapted the code for my needs in the next commit.

A1 - A2 - A3 - A4 - A5_B3' - A6 - A7
                    /*
        B1 - B2 - B3

"/*" = copy/cherry-pick/... (no 'real' reference/merge-point)

A couple of months (and a lot of commits to A ) later, I need some updates from the external Git-repository B . I added the remote B, and of course there are no common ancestors detected, since B was added in the middle and without history. However, I found a description to line up the two SHA's using a graft , so I could line up the points where the code from B was 'equal' ( B3 and A5_B3' ). I even managed to merge the changes from B to A in my local repository ( A18_B6' ):

A1 - A2 - A3 - A4 - A5_B3' - A6 - A7 - ... - A17 - A18_B6'
                    /*                            /
        B1 - B2 - B3     -  B4     -  B5     -  B6

But then it turns out, I can not push this merge to my remote repository A . ( Edit : the error I got was [remote rejected] master -> master (n/a (unpacker error)) .) Thinking of it, that might be plausible, because my remote remote repository does not know about B , so it probably does not know how/where to find/add B4 , B5 and B6 .

Maybe I could cherry-pick the changes from B ( B4 , B5 , B6 ) and add those to A17 . But that way there is no explicit merge from B , although -of course- I might adapt the commit-message. (I know, there was no explicit merge from B3 where I started, I'll get back to that.)

A1 - A2 - A3 - A4 - A5_B3' - A6 - A7 - ... - A17 - A18_B4' - A19_B5' - A20_B6'
                    /*                             /*        /*        /*
        B1 - B2 - B3                          -  B4     -  B5      -  B6

The only 'solution' I can come up with now is to add a separate ' A_B -branch' from A5 (using a branch-name explicitly referring to B ), cherry-pick the changes from B ( B4 , B5 , B6 ) in that branch, and merge that branch into A every now and then.

A1 - A2 - A3 - A4 - A5_B3' - A6 - A7 - ... - A17 - A18_B6'
                      /                             /
                    AB3'  -  AB4'   -  AB5'    -  AB6'
                   /*        /*        /*        /*
        B1 - B2 - B3     -  B4     -  B5     -  B6

In the meantime also added a smaller part of the code from another external library from another external Git-repository C . This will probably get bug-fixes to, so it may even double the trouble...

My questions are:

  • if we could start over, what would have been the best practice(s) to add (part of) B (and C)
  • given the present situation, are there other/better solutions than this ' A_B -branch' with cherry-picks

(Sorry if this is a duplicate. I tried to look for something similar. I found many answers about merging projects/forks with a 'complete' common history. And I found some answers about similar projects that needed a single merge. But I guess I may be needing to pull in some more bug-fixes later on. However, I may lack the right Git-terminology/keywords to search for.)

First off, your error has nothing to do with your merge. I never had such error and, without further context, this is the best I can find about it: git: can't push (unpacker error) related to permission issues

You can't push to " server " (git has no server, really) due to history rewrites or if your history is older than the server . That's all. If you pulled from server , did a successful merge, then push, all "atomically" (nobody else touched the server ), it will work just fine.

So, if I were at your position, and I had that problem pushing, on starting over I would check what that issue is and move on. There's nothing wrong with your merging strategy.

Also, avoid cherry-picking . From my experience that's usually a bad thing to do because it saves no reference where it came from (maybe there's a way I'm just unaware of). But some times, rare times, it's usefull. Then, I write in its commit "cherry picked" or even add where from (again, maybe there's a better approach, but since I rarely do it anyway I don't care that much). One thing is certain: if you're doing too much cherry picking, you're doing git wrong. Go back to basics .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM