tags:

views:

256

answers:

3

Hi,

I'm working on a web site project that is currently tracked in svn but is going to move to git once someone else has time to set up a new server and stuff. It's a long story, but in the meantime I've made my own git repository from some code I had, and worked on it quite a bit. I didn't use git svn clone because I'm overseas and my internet connection is weird and requires a proxy for HTTP, and it doesn't seem to let git svn through. In any case, I've been developing in my own git repository, but eventually once the project actually gets imported properly I'm going to need to rebase my work onto the git-svn cloned stuff. Will git rebase work properly for this?

One complication is that I was actually working in a virtual machine and for many commits I hadn't realized that I hadn't set the user.name and user.email config entries so the commits are from the vm's local user, which is kind of weird. Would it be better to just gather all my changes into diff files and then apply them on top of the new branch once it's created?

Another complication is that the SVN use before was kind of half-hearted, so there were actually uncommitted changes on the production server that I didn't have. Actually, I had an older revision of the code in the first place that wasn't even the SVN head, so I was missing some stuff on top of that. What is the best way to proceed?

One final question is that if I do import the SVN repository via git svn (I just checked and it seems to be working now) but I don't add an authors-file, will I later be able to rebase my changes onto a properly imported branch with an authors-file?

Oh, a new complication. I imported the SVN repository myself using git svn, a grueling process which took the better part of two days on this slow connection. However, after finally finishing the clone, I realized that in the SVN repository the code was all in a subdirectory, but in my git repository the root of the repository was also the root of directory. If this is a little confusing, it's basically like this

SVN:

\dir\codez

git:

\codez

How can I combine the two repositories? I hope that I can still use rebase, but this seems like a really weird situation. It sounds similar to submodules, but I don't think that's quite what I need.

+4  A: 

I didn't use git svn clone because I'm overseas and my internet connection is weird and requires a proxy for HTTP

It should work if you set

http_proxy=http://username:passwword@pprroxyHost:proxyPort

or you can try

http_proxyUser=username
http_proxyPassword=password
http_proxyHost=aProxyHost
http_proxyPort=aProxyPort

Will git rebase work properly for this?

General answer: yes, because you have not published your Git branch yet.
Detailed answer: you will need to rebase onto your branch first, before merging the result on master. See this answer.
This is the preferred workflow since it allows you to resolve any conflict in your branch before merging (or rebasing if you want to keep your history) your branch onto master.
Actually, you will see below that creating a special "merge" branch is actually a better idea.

hadn't realized that I hadn't set the user.name and user.email config entries

Since you have not yet published, you can use a filter-branch to modify your commits and change the user name and email

A little sh script can help

#!/bin/sh

git filter-branch --env-filter '

n=$GIT_AUTHOR_NAME
m=$GIT_AUTHOR_EMAIL

case ${GIT_AUTHOR_NAME} in
        aSystemUserName) n="TheActual Name" ; m="TheActual@mailAddress" ;;
esac

export GIT_AUTHOR_NAME="$n"
export GIT_AUTHOR_EMAIL="$m"
export GIT_COMMITTER_NAME="$n"
export GIT_COMMITTER_EMAIL="$m"
'

call this script from your repo and your are done.

I had an older revision of the code in the first place that wasn't even the SVN head, so I was missing some stuff on top of that. What is the best way to proceed?

The basic workflow in this instance is to create a new "merge" branch from your current working branch in order to isolate the rebase effort (and solve all the conflicts)
In this kind of merge where the delta is important, you must keep your working branch clean from all the changes you will need to make in order to include:

  • the code from SVN
  • the code you did not get directly from the SVN repository.

will I later be able to rebase my changes onto a properly imported branch with an authors-file?

I am not sure but I do think so. If not, as long as you have not published anything yet, you may want to use a filter-branch rename script again...

VonC
Cool thanks, this seems to be the way to go. I'm currently trying to pull down an SVN clone through `git svn` and it seems to be going well. There are actually still a bunch of uncommitted to SVN changes that I'm not sure whether I should commit, but hopefully if someone commits them later it should still be fine.
Ibrahim
I have one more complication which I have added to the original question, could you please take a look? Your answer was very helpful so it would be awesome if you could address this new problem.
Ibrahim
+1  A: 

git-rebase depends on having a common commit somewhere in the history. It also occurs within a single repository. It sounds like you are going to end up in a situation in which (a) the new git-svn imported repo is separate from yours, and (b) there will be no common commits between the two. You will probably end up needing to do this via patches, but git can help you with this. Check out the manpages for git-format-patch and git-am. The first can generate a series of patches from a range of commits, and the second can take this series of patches and apply them - and all the commit messages and such will be preserved.

This will provide you an opportunity to fix your user.name/email issue - you can simply modify them in the headers of the patches, and make sure they're set correctly in the new imported repo before you apply your patches!

The best way to deal with your out of date starting place ("older revision... that wasn't even the SVN head") is probably going to be:

  • get the SVN repo into a good state, with all changes committed
  • import it with git-svn
  • create and check out a branch at an old commit where you started working from
  • apply your patch series
  • merge this branch into master, corresponding to the current SVN head

Fortunately for me but less so for you, I've never needed to use git-svn, so I can't answer your authors-file question definitively. However, if I understand correctly, the authors-file translates SVN authors into git authors. If a the author changes on a git commit, the hash will change. It would therefore be important not to mess with this translation table, and get it right the first time.

There were a lot of questions in one here, so feel free to comment and ask for more if I missed things.

Jefromi
I was hoping to use rebase, but it's looking more and more like I'll have to use a bunch of patches. I guess that's not too bad though.
Ibrahim
A: 

You can create new unborn branch with low-level tools:

$ git symbolic-ref HEAD refs/heads/new_branch

With modern git you can rebase whole branch by using --root option of "git rebase".

This might, or might not, help in your situation. YMMV.

Jakub Narębski