|Version 6 (modified by packy, 4 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.
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.
Let's say you're working on some stuff that's not quite ready to be checked in, but you suddenly need to work on something else. You can type git stash, which will record the current state of your work and give you a clean working directory again. You can then make whatever changes you want to your working directory, commit them, dcommit them to SVN, and then type git stash pop to get what you were working on before back. You can also build a stack of stashed work by repeatedly making changes followed by git stash commands; you can then list these stashed modifications with git stash list. For full documentation on the fun of git stashing, type git stash --help .
Another benefit of git is it's extremely easy to create a branch in your local git repository:
git checkout master git branch rt1739 git checkout rt1739
This makes a local branch off your master branch called "rt1739". You can commit changes to this branch that won't affect your master branch, and you can switch back and forth between your local branches and your master branch. In addition, each of these branches is connected to the trunk of the SVN repository, so any changes dcommitted from these branches will automagically be merged into the SVN trunk and appear in your local trunk the next time you run git svn rebase when you have your trunk checked out.
Other developers may access your local branches, but in order to do so, they would need to be able to access your git repository.
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?