1

Years ago I created a public repository of a SourceForge project on Github. Back then, the project only supported CVS, so I used git cvs to periodically sync my repository with the original.

There have not been any commits to the CVS repository for a long time, and now I found out that they moved to git as well (albeit on Sourceforge, not Github).

My question is now: How do I merge the changes in the SF git repository into my repository?

What I tried so far:

  1. Add new remote repository 'upstream' pointing to the SF git repo
  2. git fetch upstream
  3. git checkout master
  4. git merge upstream/master

The last step works without error, but git status tells me that master & origin/master have diverged. Doing a git pull now results on lots and lots of conflicts ("CONFLICT (add/add)").

1100101
  • 135
  • 1
  • 9

2 Answers2

2

If you've simply been rebasing your modifications onto branches imported from cvs, this might be very easy. My first attempt would be to match commits by identifiable text in their commit messages, then try to match patch-ids

Setup: find the current base commit for your work:

currentbase=$(git merge-base master master@{u})
git show -s $currentbase

Now to find a corresponding commit in upstream/master:

git checkout upstream/master
git show -s :/"some regex for unique-looking text in the $currentbase message"
# and if that's right
newbase=`git rev-parse !git:$`  # !git:$ is last arg to previous git command

and if that doesn't work, try finding a commit that applies the same patch:

patchids=`mktemp`
git rev-list upstream/master \
| while read; do 
        git diff-tree -p $REPLY | git patch-id
  done >> $patchids

# hunt up a commit that makes the same changes as $currentbase
set -- `git diff-tree -p $currentbase | git patch-id`
grep $2 $patchids
# and if it finds one
set -- $(!grep)  # !grep is whole of last grep command
newbase=$2

However you find it, when you get the right one

git rebase --onto $newbase master@{u} master
git branch -u upstream/master

From there, you can do as usual, plain git rebase defaults to the current upstream.

jthill
  • 55,082
  • 5
  • 77
  • 137
  • I like that approach to find common history (instead of the manual inspection I was mentioning in my answer). +1 – VonC Nov 30 '14 at 02:49
  • I followed your instructions, but unfortunately it didn't work as expected. The 1st issue is that the HEAD commit of my master branch was made be myself ("updated gitignore"), so I can't find a reference on upstream/master. HEAD-1 would actually work though. 2nd problem is, that `git show -s ...` on the upstream/master branch finds the commit hash from the wrong branch (it's the hash from master instead of upstream/master). Third, even when setting currentbase and newbase manually, the rebase command fails: "Error: no upstream configured for branch 'master'. fatal: needed a single revision" – 1100101 Nov 30 '14 at 11:50
  • Nevermind. It worked! I had accidentally deleted the upstream info on master, which was the cause for the error message. – 1100101 Nov 30 '14 at 12:05
  • I have a followup question: Now that local branch 'master' is tracking 'upstream/master' (which is the SF repository), I cannot push the local changes to github. `git push origin master` rejects the push, because my "current branch is behind its remote counterpart". – 1100101 Nov 30 '14 at 19:02
  • Your old git history is pretty much useless now. You could preserve it if you want, rename the branch or something for safety, just for that belt-and-suspenders feeling. – jthill Nov 30 '14 at 19:39
  • One more thing I really should have mentioned, you can `git config remote.upstream.pushurl u://r/github/repo`, and your `upstream` remote will pull from the main upstream but push to yours. – jthill Nov 30 '14 at 21:31
0

The issue is that the histories of upstream/master and master are completely different (every commit has a different SHA1)

You need to look at the history of upstream/master, and determine which are the commits from the Sourceforge Git repo which are new compared to your own master history.

Then, you can:

  • create a branch from the last common commit on your master branch
  • git cherry-pick all those commits from upstream/master to that new branch (which starts from master)
    (note: you can cherry-pick a range of commits)
  • then merge that new branch to master.
Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250