Your SlideShare is downloading. ×
Git for svn users
Git for svn users
Git for svn users
Git for svn users
Git for svn users
Git for svn users
Git for svn users
Git for svn users
Git for svn users
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Git for svn users

154

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
154
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
3
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. (Easy) GIT for SVN users ...showing that (easy) git is easier to use overall than subversion The Basics Core commands: svn checkout svn+ssh://USER@MACHINE.ORG/PATH/TO/MO DULE/trunk MODULE eg clone ssh://USER@MACHINE.ORG/PATH/TO/M ODULE.REPO svn status eg status svn update eg update svn diff eg diff svn add FILE eg add FILE svn commit eg commit eg push Other common commands: svn blame FILE eg blame FILE svn cat FILE eg cat FILE svn help [COMMAND] eg help [COMMAND] svn info eg info svn mv OLDNAME NEWNAME eg mv OLDNAME NEWNAME svn resolved PATH... eg resolved PATH... svn revert PATH... eg revert PATH... svn rm FILE... eg rm FILE... SUMMARY: checkout/clone and commit are slightly different, the rest of the basic commands are the same. Switching to a different version of the repository Switch to an older version, or possibly a newer version (see the Revision specifiers section below). svn update -r REVISION eg switch REVISION Switching the working copy over to another branch svn switch svn+ssh://USER@SVN.MACHINE.ORG/PATH/TO/MODULE/branche s/BRANCHNAME eg switch BRANCHNAME Creating tags Create a tag in a public repository svn cp . eg tag TAGNAME
  • 2. svn+ssh://USER@SVN.MACHINE.ORG/PATH/TO/MODULE/tags/TAG NAME eg push --tag TAGNAME Create a local tag that does not appear in a public repository Not Available eg tag TAGNAME Creating branches Create a branch in a public repository svn cp . svn+ssh://USER@SVN.MACHINE.ORG/PATH/TO/MODULE/bran ches/BRANCHNAME eg branch BRANCHNAME eg push --branch BRANCHNAME Create a local branch that does not appear in a public repository Not Available eg branch BRANCHNAME Committing changes For the next three examples, I am assuming that the distinction between recording locally or centrally is not relevant. If you want to record changes on some public server, follow each of the eg commit steps with an 'eg push' Record changes, using the log message specified on the command line svn commit -m MESSAGE eg commit -m MESSAGE Record changes, using the text from a specified file for the log message svn commit -F FILE_WITH_LOG_MESSAGE eg commit -F FILE_WITH_LOG_MESSAGE Record changes to just certain files svn commit FILE1 FILE2... eg commit FILE1 FILE2... Record changes locally only (perhaps you are offline or just need to checkpoint your work without going through a peer review yet) Not Available eg commit Modify the last commit (possibly including extra files, more changes, or just a different log message); note that this is a bad idea if the previous commit has been pushed to a public location. Not Available eg commit --amend Stashing changes away Stash changes away and return to a clean slate cd /PATH/TO/TOP/OF/REPOSITORY eg stash [save OPTIONAL STASH DESCRIPTION TEXT] svn diff > NAME-OF-STASH.PATCH Applying an old stash cd /PATH/TO/TOP/OF/REPOSITORY eg stash apply [OPTIONAL STASH DESCRIPTION TEXT] patch -p0 < NAME-OF-STASH.PATCH Listing available stashes
  • 3. ls *.PATCH # Hope you don't have lots of other patches eg stash list Reverting changes Revert changes to files foo.cc and baz.py since the last commit svn revert foo.cc baz.py eg revert foo.cc baz.py Revert all the changes since REVISION (see the Revision specifiers section below) cd /PATH/TO/TOP/OF/REPOSITORY eg revert --since REVISION svn diff -r REVISION | patch -p0 -R Revert all the changes made in REVISION (OLDREVISION below is obtained by taking REVISION and subtracting one; see the Revision specifiers section below) cd /PATH/TO/TOP/OF/REPOSITORY eg revert --in REVISION svn diff -r OLDREVISION:REVISION | patch -p0 -R Showing changes to file contents To understand the form of REVISION, REV1, etc. in this section, see the Revision specifiers section below. Show the changes made since a specified REVISION, in patch format svn diff -r REVISION eg diff REVISION Show the changes between REV1 and REV2 to FILE svn diff -r REV1:REV2 FILE eg diff REV1 REV2 FILE Note: You can add a double dash ("--") before FILE in the eg case to distinguish between files and revisions, if needed. Show the changes between the branch BRANCH and revision REVISION (for the subversion case, we have to assume that REVISION was a change made to trunk, otherwise the svn command changes). svn diff svn+ssh://USER@SVN.MACHINE.ORG/PATH/TO/MODULE/branches/BR ANCH svn+ssh://USER@SVN.MACHINE.ORG/PATH/TO/MODULE/trunk@REVI SION eg diff BRANCH REVISION Show the changes between the branch BRANCH and the working copy Not Available eg diff BRANCH Show the changes between the tag TAG and mainline development (trunk for svn and master for eg) svn diff svn+ssh://USER@SVN.MACHINE.ORG/PATH/TO/MODULE/tags/TAG svn+ssh://USER@SVN.MACHINE.ORG/PATH/TO/MODULE/trunk eg diff TAG master Show the changes between the tag TAG and the working copy Not Available eg diff TAG Show the changes on the current branch since 2 commits before the last one on this branch svn log # Look for the revision corresponding to two commits ago eg diff HEAD~2
  • 4. svn diff -r REVISION_WE_LOOKED_UP (Explanation: Even if you know the current revision number in subversion, you can't always simply subtract 2, because the last two revisions may have been for different branches. In eg, HEAD means the current branch (and branches always point to their most recent commit), so you simply need to request two commits before it.) Creating new repositories Create a new empty repository and associated working copy svnadmin create /RANDOM/PATH/FOR/REPOSITORY mkdir project svn mkdir file:///RANDOM/PATH/FOR/REPOSITORY/project/{trunk,tags,branches} -m "Set up initial repository structure" cd project svn checkout file:///RANDOM/PATH/FOR/REPOSITORY/project/trunk project eg init cd project Create a new repository and associated working copy, based on an import of files in an existing directory svnadmin create /RANDOM/PATH/FOR/REPOSITORY cd project svn import project file:///RANDOM/PATH/FOR/REPOSITORY/project/trunk -m "Initial import of project" eg init rm -rf project eg add . svn checkout file:///RANDOM/PATH/FOR/REPOSITORY/project/trunk project eg commit -m "Initial import of project" cd project Merging Merge all changes that were not previously merged in from branch BRANCH into the working copy svn info svn+ssh://USER@SVN.MACHINE.ORG/PATH/TO/MODULE/branches/BRA NCH eg merge BRANCH <Somehow pick out which changes have not yet been merged in, to obtain the revision range REV1:REV2> svn merge -r REV1:REV2 svn+ssh://USER@SVN.MACHINE.ORG/PATH/TO/MODULE/branches/BRA NCH Caveats for svn: If you obtain the wrong REV1 and REV2 for subversion, you are likely to get extra spurious changes and conflicts. Rerunning the subversion command a second time guarantees that you'll get conflicts, whereas the eg command will do nothing if immediately rerun. Also, you'll need to carefully check the output in subversion, because the results will likely be wrong if any renames were done on BRANCH. Finally, there will be no record of the merge occurring; the commit logs for the merged changes will not be shown when running svn log, and there's no way to recover that information..unless you manually include any such details in your commit message after performing
  • 5. the merge. That also means that when you are performing a merge, you should carefully look at all preceding log messages for prior merge information. Staging changes Mark the current changes in some files as being "ready to be committed" Not Available eg stage FILE1 FILE2... Note for users of traditional git: "stage" and "add" are aliases. Get the changes to FILE1 and FILE2 that are staged (i.e. "ready to be committed") Not Available eg diff --staged FILE1 FILE2 Get all unstaged changes (i.e. changes that haven't explicitly been marked as ready to be committed) Not Available eg diff --unstaged Get all changes (both staged and unstaged) to a file Not Applicable eg diff FILE Commit all changes (whether staged or not) Not Applicable eg commit -a Note: The -a is short for --all-known. Commit only the staged changes Not Available eg commit --staged Unstage the changes to a file Not Available eg unstage FILE Obtaining a subset of the files in a repository This is a feature of subversion that may be dropped in the future (look for "detachability" in the email pointed to by that link), in order to gain some of the advantages of other systems like git. Get a copy of just one file, with no associated working copy svn export svn+ssh://USER@MACHINE.ORG/PATH/TO/MODULE/trunk/PATH/TO/FILE Not Available Check out one subdirectory, and have it serve as a working copy svn checkout svn+ssh://USER@MACHINE.ORG/PATH/TO/MODULE/trunk/PATH/TO/SUBDI R Not Available Pulling changes directly from other developers This section skips some of the more advanced pulling operations you can do with "refspecs", remote tracking branches, and named remote repositories. Pull the changes from someone's published http repository (assumes they only have one branch in their repository, or that you have pulled from it before) Not Available eg pull http://WWW.SERVER.ORG/~USER/PATH/TO/REPO.GIT Pull the changes from the stable branch of Bob's project in his home directory Not Available eg pull --branch stable /HOME/BOB/PROJECT Pull changes from both the testing and funny-stuff branches of a fellow developer's repository on a remote machine (accessed via ssh), merging both branches into your working copy. Then after seeing the merge succeed and be committed, decide to undo the work. Not Available eg pull --branch testing --branch funny-stuff USER@MACHINE.ORG:/PATH/TO/PROJECT
  • 6. eg reset --working-copy ORIG_HEAD Note: ORIG_HEAD is always set at the start of a merge or pull operation to enable easily undoing these operations. Publishing a copy of your local repository Publish a copy of your repository on the a machine you have ssh access to <Configure an svn server to run on the remote machine; see chapter 6 of the svnbook> eg publish USER@EG.EXAMPLE.COM:PUBLI C_HTML/MY_COOL_PROJECT ssh ADMIN@SVN.EXAMPLE.COM "svnadmin create /PATH/TO/REPOSITORIES/SVN-MIRROR" <Configure remote svn repository's pre-revprop-change and start-commit hook script to make the repository read- only, or deal with your "recipe for disaster"; see the repository replication section of the svnbook> svnsync initialize http://SVN.EXAMPLE.COM/SVN- MIRROR /PATH/TO/LOCAL/REPOSITORY --username SYNCUSER --password SYNCPASS svnsync synchronize http://SVN.EXAMPLE.COM/SVN- MIRROR --username SYNCUSER --password SYNCPASS Caveats for svn: The published subversion repository has a very limited set of capabilities relative to the eg/git case. For the subversion case, the copied repository has severely restricted capabilities. In particular, one cannot independently commit to the local and remote repository and then merge changes between the two repositories as needed. If one tries to use the copied subversion repository as anything other than a read-only mirror (something the svn developers call a "recipe for disaster"), then the repositories diverge with no reasonable method of reconciliation; they can no longer be used for the same project. Update the remote repository copy svnsync synchronize http://SVN.EXAMPLE.COM/SVN-MIRROR --username SYNCUSER --password SYNCPASS eg push Getting a checkout based on the repository copy svn checkout http://SVN.EXAMPLE.COM/SVN- MIRROR/trunk PROJECTNAME eg clone http://EG.EXAMPLE.COM/~USER/MY_COOL _PROJECT PROJECTNAME Finding the commit that introduced a bug An important note: All of the steps below for eg can be done offline, disconnected from the original repository that you cloned from -- and as a side effect, the operations are also much faster in eg. For svn, log and update both require network connectivity to the original repository and operations are relatively slower. This speed and online vs. offline behavior of eg and svn is true of other operations as well, but the distinction is even more pronounced in this use case than in others. Getting started at tracking down the buggy commit <Somehow determine a good revision from history, as well as the bad revision (usually the <Somehow determine a good revision from history, as well as the bad revision (usually the current one). Typically, one uses 'eg log' and
  • 7. current one). Typically, one uses 'svn log' and one's own memory for this.> one's own memory for this.> eg bisect start Doing the first split <Somehow determine a revision in the middle of the good and bad ones. If there are few commits on other branches, averaging the two might work. Otherwise, use 'svn log' and start counting.> eg bisect bad [REVISION_OTHER_THA N_CURRENT_ONE] svn update -r REVISION_IN_MIDDLE eg bisect good REVISION If you have to manually test each revision, repeat the following steps as often as necessary: Checking out a given split <Compile, link, test; see if this revision is good or bad.> <Compile, link, test; see if this revision is good or bad.> If the most recently tested revision is good, do the following and jump back to the "checking out a given split" step above. <Somehow determine a revision in the middle of the new good one and the previously determined bad one. If there are few commits on other branches, averaging the two might work. Otherwise, use 'svn log' and start counting.> eg bisect good svn update -r REVISION_IN_MIDDLE If the most recently tested revision is bad, do the following and jump back to the "checking out a given split" step above. <Somehow determine a revision in the middle of the new bad one and the previously determined good one. If there are few commits on other branches, averaging the two might work. Otherwise, use 'svn log' and start counting.> eg bisect bad svn update -r REVISION_IN_MIDDLE If you have a script that can compile, link, and test whether a revision works, you can simply use: Automate all the testing and splitting steps in a single command Not Available eg bisect run NAME_OF_SCRIPT Returning the working copy to normal when you are done svn update eg bisect reset Removing recent commits from the current branch Note: This section is not about reverting changes from previous commits by recording a new commit with the old contents. See the reverting changes section for that; this section is about actually removing recent commits from the current branch. This is rarely a good thing to do with commits that have been made available to other people (it can break future merging), but can come in quite handy for commits that have been kept local. Remove the last 3 commits from the current branch, also returning the working copy to the state of the repository before the last 3 commits. (Note that HEAD always refers to the current branch in eg) Not Available eg reset --working-copy HEAD~3 Remove the last 2 commits from the current branch, but leave the working copy as it is (could be used, for example, to turn the last two commits into a single commit). Not Available eg reset HEAD~2 Retroactively place the last 6 commits of the current branch on a different branch, and switch to that
  • 8. branch Not Available eg branch NEW_DIFFERENT_BRANCH eg reset --working-copy HEAD~6 eg switch NEW_DIFFERENT_BRANCH Technically, one can also add commits to the current branch and move the current branch to match an entirely different branch... Maintaining an independent patch set Note: An independent patch set would typically be tracked in eg using a separate local branch with all the patches applied in order. This usually doesn't make sense in subversion, since branches are shared and global, so an independent patch set is typically kept as a series of files. One can use eg with a set of separate patch files easily, but maintaining a patch set as a separate branch in subversion makes no sense -- svn has no facility for updating the patches to be relative to new changes on trunk. Using subversion, you must repeat the following sequence for each patch: Update the next patch in the series (whose name we refer to as PATCH, as a placeholder) rsync -a ./ ../extra-working-copy patch -p1 < PATCH <Carefully check the patch output to see if there were any conflicts or hunks that did not apply. Manually fix up any such problems> diff -pru ../extra-working-copy ./ > PATCH Using eg, you can update the whole patch set as follows: Take all the patches on the current branch since the branchpoint from BRANCH, and update the patches to be relative to the current tip of BRANCH. Not Available eg rebase --against BRANCH With eg if any patches could not be automatically rewritten with the above command, then when the above command stops simply fix up the relevant files and then run Resolving conflicts when rebasing Not Applicable eg resolved FILE... Not Available eg rebase --continue Note that eg diff, eg status, and other commands may come in handy in determining how to resolve the conflicts. Note: Using eg, there is a powerful --interactive flag to rebase that allows you to easily split, combine, remove, insert, reorder, or edit commits. Run 'eg help rebase' for details. Tracking changes from multiple remote repositories List all named remote repositories ('remotes' for short) Not Available eg info (Just look for the "Named remote repositories" section of the output of eg info) Add a new remote, giving it an associated name Not Available eg remote add REMOTENAME URL You can use the nickname of a remote repository in the place of a URL, but there are also some additional things you can do with remotes:
  • 9. Create/update a local branch named REMOTENAME/BRANCH for each branch of a remote (such branches are called remote tracking branches) Not Available eg fetch REMOTENAME Remote tracking branches can be used the same as normal branches (but it's bad form to checkout/switch to such branches and commit to them; create a separate branch instead). Some examples to make it clear: List all remote tracking branches Not Available eg branch -r Merge the remote tracking branch bob/stable into the current branch Not Available eg merge bob/stable Get a history of the changes on the jim/eye-candy branch Not Available eg log jim/eye-candy Create a new branch named my-testing based off of the remote tracking branch jenny/testing Not Available eg branch my-testing jenny/testing Pull changes from the 'fixes' branch of a remote and merge it into the current branch (i.e. standard pull behavior) AND also update all remote tracking branches associated with the remote (i.e. act as if 'eg fetch REMOTENAME' was also run) Not Available eg pull --branch fixes REMOTENAME Delete a named remote repository, including all related remote tracking branches (and any special configuration settings for the named remote) Not Available eg remote rm REMOTENAME Grab updates from all(*) named remote repositories, i.e. run 'eg fetch REMOTE' for each remote Not Available eg remote update (*) Remotes can be manually configured to be skipped, so this may not really mean 'all' remotes. Special Note: Revision specifiers Version control systems use different methods to refer to different versions of the repository. svn counts forward globally, while eg counts backwards relative to each branch. Thus a typical version for svn would be something like "218" while for eg it would be "master~23". You can use the "svn log" and "eg log" commands to get the name of a revision for a particular commit. The tilde character ("~") is used in eg since minus signs can serve as dashes in branch names (master-23 could be a branch).

×