Contents
Using git-svn
If you install the devel/git-subversion port, you can use git svn to obtain code and push code back to a Subversion repository from a git tree.
The following clone operations are encapsulated in a script in the base system under tools/tools/git/git-svn-init
# for docs: $ GIT_REPO=git://github.com/freebsd/freebsd-doc.git $ GIT_SVN_ROOT_URI=svn.freebsd.org/doc $ GIT_SVN_URI=repo.freebsd.org/doc # for ports: $ GIT_REPO=git://github.com/freebsd/freebsd-ports.git $ GIT_SVN_ROOT_URI=svn.freebsd.org/ports $ GIT_SVN_URI=repo.freebsd.org/ports # for source: $ GIT_REPO=git://github.com/freebsd/freebsd.git $ GIT_SVN_ROOT_URI=svn.freebsd.org/base $ GIT_SVN_URI=repo.freebsd.org/base $ GIT_SVN_PUSH_URI=$GIT_SVN_URI # do the cloning $ git clone $GIT_REPO freebsd $ cd freebsd # init git-svn to point to the subversion repo: $ git svn init -Thead --rewrite-root=svn+ssh://$GIT_SVN_ROOT_URI svn+ssh://$GIT_SVN_URI . # Committers need to use proper URL for dcommit $ git config --add svn-remote.svn.pushurl svn+ssh://$GIT_SVN_PUSH_URI # Now you'll want to look in .git/config and make sure that # it has a config section that looks like this: #[svn-remote "svn"] # url = svn+ssh://repo.freebsd.org/base # rewriteRoot = svn+ssh://svn.freebsd.org/base # pushurl = svn+ssh://repo.freebsd.org/base # fetch = head:refs/remotes/origin/trunk # # Now what we have to do is get 'master' to be tracking 'svn_head': # Now make a git branch 'trunk' for git-svn to follow. What we want to do it set it to point to the final commit in origin/svn_head. $ git update-ref refs/remotes/origin/trunk `git show-ref origin/svn_head|cut -d" " -f1` # git-svn really needs this branch # Sync with the FreeBSD svn repo and reconstruct the necessary metadata. # This should be pretty fast and output looks like a list of revisions that start above 100,000. $ git svn fetch # Arrange to have 'master' reference 'trunk' $ git checkout trunk; git branch -D master # delete master $ git checkout -b master trunk # and have master hang off trunk # Get pull requests from the repos: $ git config --add remote.origin.fetch '+refs/pull/*:refs/remotes/origin/pull/*' $ git fetch # Finally do a final update from head. $ git svn rebase
Now you can periodically sync to svn using git svn rebase and you can push small changes back to svn using git svn dcommit, but read on.
Things to keep in mind:
Never git merge branches, unless you know what you're doing.
Always git rebase your work on top of master, then git svn dcommit can push the top commits to svn.
Always double-check with git svn dcommit -n to see what would happen.
- When adding new files, you must add certain svn properties before pushing upstream. See information below.
While git-svn now allows you to set svn:mergeinfo when committing, this is so fragile that the FreeBSD projects discourages its use. Please use svn(1) for merging, sorry.
If you do git mv, the git svn dcommit seems to preserve the move operation
Merging pull requests from github using git-svn (FreeBSD committers only)
# # Begin single port submit via pull request: # # Get most up to date version of everything from github (all the new pull requests) $ git fetch # Make sure you local copy is up to date $ git svn rebase # Now get the user's change onto the git-svn branch: # ...an editor will pop up right after you run this command, see the next section for what to do. $ git rebase -i --onto master origin/master origin/pull/21/head # Inside the editor you'll want to "squash" the commits so that SVN only gets a single commit. # If there is only a SINGLE "pick" line like: # "pick 251f162 Try to fix @sample usage" # then just save+quit out of your editor. # # However if there are multiple "pick" lines you will want to flatten (squash) all of the changes into a single commit. # # Example, if you see this: # # pick 251f162 Try to fix @sample usage. # pick 6c96c06 using VAR as both OPTION and PLIST_SUB doesn't seem to work. # pick c259e63 Use auto PLIST_SUB stuff. # # Change it to this: # # pick 251f162 Try to fix @sample usage. # s 6c96c06 using VAR as both OPTION and PLIST_SUB doesn't seem to work. # s c259e63 Use auto PLIST_SUB stuff. # # Save+quit the editor, then another editor will pop up for you to combine the commit messages. # Then cleanup the commit message and save+quit. # # Now you are ready for commit... almost, you must add freebsd properties. # # Now add FreeBSD required properties. # # You must use Git 2.3.0 or higher which has this fix to git-svn for svn properties: # https://github.com/git/git/commit/83c9433e679635f8fbf8961081ea3581c93ca778 # XXX: at this point you'll need to add svn properties to the files # # $ git svn propset REQUIRED_PROPNAME REQUIRED_PROPVAL files... # # Probably something like: $ git svn propset svn:keywords "FreeBSD=%H" devel/py-tipper/Makefile $ git svn propset fbsd:nokeywords yes devel/py-tipper/pkg-descr $ git svn propset fbsd:nokeywords yes devel/py-tipper/distinfo # make sure the commits look OK: $ git svn dcommit -n # Show the actual diff. $ git diff `git svn dcommit -n | grep '^diff-tree'| cut -f 2,3 -d" "` # actually commit it... $ git svn dcommit
See also 5.3.7. Adding and Removing Files in Committer's Guide about the properties in detail.
Working on a github branch
This is a work in progress section. Sometimes people wish to collaborate with each other outside of the projects tree using github. This section hopes to document the best practices there, as well as how to tie the work flow into pushing changes upstream into FreeBSD. You should read and understand the prior sections.
Merging a branch from github to FreeBSD
This assumes that you've set things up as above, and you have also been using a separate repo to do the development on github and you are using the repo as setup above to push in. Hopefully this section will be refined as necessary to avoid multiple repos. It should be considered experimental in nature
# Get most up to date version of everything from github (all the new pull requests) $ git fetch # Make sure you local copy is up to date $ git svn rebase # Now get the user's change onto the git-svn branch: # ...an editor will pop up right after you run this command, see the next section for what to do. $ git rebase -i --onto master origin/master origin/branch-to-merge # Inside the editor you'll want to "squash" the commits so that SVN only gets a single commit. # If there is only a SINGLE "pick" line like: # "pick 251f162 Try to fix @sample usage" # then just save+quit out of your editor. # # However if there are multiple "pick" lines you may want to flatten (squash) all of the changes into a single commit. # It all depends on how 'clean' the branch you've created is. Each commit here will wind up in the FreeBSD repo when # it is git svn dcommit'd. # # Example, if you see this: # # pick 251f162 Try to fix @sample usage. # pick 6c96c06 using VAR as both OPTION and PLIST_SUB doesn't seem to work. # pick c259e63 Use auto PLIST_SUB stuff. # # Change it to this: # # pick 251f162 Try to fix @sample usage. # s 6c96c06 using VAR as both OPTION and PLIST_SUB doesn't seem to work. # s c259e63 Use auto PLIST_SUB stuff. # # Save+quit the editor, then another editor will pop up for you to combine the commit messages. # Then cleanup the commit message and save+quit. # # Now you are ready for commit... almost, you must add freebsd properties. # # Now add FreeBSD required properties. # # You must use Git 2.3.0 or higher which has this fix to git-svn for svn properties: # https://github.com/git/git/commit/83c9433e679635f8fbf8961081ea3581c93ca778 # XXX: at this point you'll need to add svn properties to the files # # $ git svn propset REQUIRED_PROPNAME REQUIRED_PROPVAL files... # # Probably something like: $ git svn propset svn:keywords "FreeBSD=%H" devel/py-tipper/Makefile $ git svn propset fbsd:nokeywords yes devel/py-tipper/pkg-descr $ git svn propset fbsd:nokeywords yes devel/py-tipper/distinfo # make sure the commits look OK: $ git svn dcommit -n # Show the actual diff. $ git diff `git svn dcommit -n | grep '^diff-tree'| cut -f 2,3 -d" "` # actually commit it... $ git svn dcommit