2

I've got a repository which was created simply by checking out upstream version at some point. I know the exact commit it came from.

Is there an easy way to merge the remaining commits now? How can I do "merge everything after xyz" disregarding missing common history before that commit?

viraptor
  • 33,322
  • 10
  • 107
  • 191

3 Answers3

2

git format-patch ancestor..HEAD on the source repo, and git am on the target repo would probably work.

Useless
  • 64,155
  • 6
  • 88
  • 132
  • For some reason I'm getting conflicts after that. Browsing repo to spot the problem... – viraptor Sep 26 '11 at 16:16
  • I did `format-patch hash_I_have..last_has` but then there's a merge on the path, git tries to apply the modification twice to the same file. – viraptor Sep 26 '11 at 16:18
  • Do you mean there's already a merge between the two repos? Or some other merge local to the source repo? Or ... something else? – Useless Sep 26 '11 at 16:25
  • There's a split and merge in the upstream repo. I don't have those commits in the local one. Importing fails on the merge point. (patch tries to delete files which were already deleted) – viraptor Sep 26 '11 at 16:27
1

A good solution for exactly this problem is to use git's "grafts" mechanism, which is designed for stitching together different histories. There's some explanation here:

... and a nice tutorial here:

As those links suggest, you will probably want to use git filter-branch after adding the graft to rewrite your history, enabling other people to clone the complete history, including everything grafted in. (Although this should have the usual warnings about rewriting history.)

Community
  • 1
  • 1
Mark Longair
  • 446,582
  • 72
  • 411
  • 327
1

One option here would be to rebase your work on-top of the current HEAD of the repository you branched from.

What git rebase does there is wind back your branch to the common ancestor, then fast-forward all the new commits on the branch you are rebasing against, and lastly, tries to apply each of your commits in turn until you have a linear history including everything from the other branch, followed by all of your own work.

Warning: never rebase branches where you have shared your state with someone else or another branch and you care about maintaining that relationship: this essentially rewrites history and will create entirely new commits with no relationship to your existing ones. Further information about rebasing can be found here: I recommend reading that page before you go on.

With that caveat in mind you would do the following:

git remote add source git://host.that.has.source/repo 
git fetch source
git rebase source/master

I've made a few assumptions here.

  • That you have access to the original repository: you need to import all the commits since you made your original branch for this to work.

  • That you want to keep in step with the master branch of that repository: if you want to use a different branch replace the word "master" with the name of the remote branch you want to rebase against (git branch -rto see them all).

Note: when you run the rebase command, you may be faced with situations where you have to resolve conflicts: do so in the normal way.

In the case of the commit you mentioned in the comments which was previously cherry-picked or merged and is causing conflicts, it should be safe to assume that the upstream copy of that code trumps your version: when git tries to apply that commit and encounters errors, you can just git reset --hard HEAD and then git rebase --continue to use their version.

jkp
  • 78,960
  • 28
  • 103
  • 104
  • Using rebase will linearize all the history that's being reapplied, though. You can use the `--preserve-merges` parameter to rebase to try to get around this, but I'm not sure how well that works in practice. – Mark Longair Sep 26 '11 at 17:13