Version 5 (modified by packy, 5 years ago)

--

First, we need to fetch a copy of the repository.

    git svn clone -s -r 34140 https://svn.perl.org/parrot # choose some recent-ish commit

-s is for --stdlayout which presumes the svn recommended layout for tags, trunk, and branches.

-r is for the revision to start taking history from. If you want to include all of the history, just leave that option off, but it will take a very long time, and you really don't need all of it. You could also ask around for a tarball of the repo with history if you don't want to use the bandwidth and time.

This will create a directory in the current directory named 'parrot'. If you want to specify the directory to create, pass one more argument.

Now, start working on patches. The simplest way to work, without local branches, is:

    hack; hack; hack; hack

    git diff # look at differences since the last commit

If you want to commit all of these changes, run:

    git commit -a

and enter your commit message. This creates a local commit only. It hasn't been pushed to the SVN server yet. If you only want to add changes from some files but not others, run:

    git add file1 file2 file3 ...
    git add -i file4 # if you only want to add some diff hunks and not others
    git commit

and enter your commit message. After this, 'git diff' will still show the uncommitted changes. While you're adding changes to be committed, you can run 'git diff --cached' to see what's going to go in the next commit.

After you've made however many commits, you can push up to the svn server with:

    git svn dcommit

That will also bring your local tree up to date. To bring your tree up to date in general, run:

    git svn rebase

This will update your local checkout and then re-apply your local un-submitted commits on top of the new trunk.

Neat Tricks

One of the neat things about git is that you can modify your commits before you push them up to the SVN server. Let's say you've made 10 commits to your local git repository, but you want it to look like two when it gets pushed up to SVN. All you need to do is type

    git rebase -i HEAD~10

And git will launch your $EDITOR and allow you to perform what's referred to as an "interactive rebase."

    pick 08464ae bug 9074 Fix bad logging call.
    pick 8750643 bug 9995 Run the supplied architecture through arch_extract() to change 'x64' into 'x86_64' when it occurs.
    pick af6f7ae bug 9995 Make sure the architecture string occurs on word boundries (ie, it's not part of a larger word)
    pick 8e4ef0c Don't generate a warning for generic apps.
    pick 1e4d124 Add a module for handling script-based custom applications.
    pick 808607d bug 9879 Resolve paths to entity IDs at the start of a process.
    pick e02a0db bug 9879 Cosmetic code formatting changes.
    pick 3e1cc94 bug 10010 Added an optional comparator argument to compare_homes
    pick 218805c bug 10010 Added comparator argument to default implementation for consistency
    pick 21e20fa bug 10010 Made procs_under_home use compare_homes to handle case insensitivity on windows

    # Rebase 05e760e..21e20fa onto 05e760e
    #
    # Commands:
    #  pick = use commit
    #  edit = use commit, but stop for amending
    #  squash = use commit, but meld into previous commit
    #
    # If you remove a line here THAT COMMIT WILL BE LOST.
    # However, if you remove everything, the rebase will be aborted.
    #

If you change any of the lines that start with "pick" to start with "squash" instead, when you exit your $EDITOR, that commit will be squashed into the commit above it and you'll be popped back into $EDITOR to combine the commit messages into one. You can also squash multiple commits into more than one commit in a single session; $EDITOR will be fired up for each of the resulting commits for you to combine the commit messages.

You can also reorder commits just by moving them up or down in the list, and you can drop commits entirely by removing them from the list.

Attached to this page is a perl script called gsquash which uses git log to look for commits that haven't been pushed to SVN yet and builds the appropriate git rebase -i HEAD~n command.

Questions

We've heard a lot about how git will ease the pain of working in branches; can you provide an example, showing a branch that all committers can collaborate on, that can be rebased against trunk as needed, and then merged back to trunk?

More information on git-svn

 http://utsl.gen.nz/talks/git-svn/intro.html

Attachments