When moving to Git from SVN, there are some conceptual conflicts that causes a lot of troubles on daily work. This document intends to describe some basic differences between SVN and Git, so SVN users can learn faster and probably avoid problems.
The first big difference between Git and SVN is Git makes possible to have decentralized workflow when collaborating to other developers, while SVN is fully centralized.
On decentralized workflow you can duplicate (fork) a git repository, share this repository with friends while the original has it's own activity. It is also possible to send differences from duplicated repository to the original and fetch differences from original as well.
On centralized workflow, every change needs to be committed to a unique remote repository. Despite the fact you can have SVN mirrors, it is still centralized, because mirrors also get/send changes from/to central repository.
svn co https://svn.code.sf.net/p/tikiwiki/code/trunk tikiwiki
git clone firstname.lastname@example.org:tikiwiki/tiki.git tikiwiki
When working on SVN workflow, every commit goes directly to SVN server and will be available to other developers when they update their working copies.
But on Git it is very different. When you initialize a git folder, you will have your project files on your working space, a new local Git repository at the root of your project and optionally, a remote repository, like we have on Github or Gitlab.
When you commit your changes using Git, these changes will be saved only in your local repository. To make your commits available to other devs, you have to *push* your changes to a remote repository. Also, if you want to get changes from other devs and apply on your working space, you have to *pull* these changes from remote repository.
echo 'my new change in a file' > README svn add README svn ci -m '[FIX] Added changes on README'
echo 'my new change in a file' > README git add README git commit -m '[FIX] Added changes on README' # It is possible to commit more changes before sending to remote. # After done, just push changes to remote repository git push
To create branches on SVN, you have to create a branch on remote repository as well, so your team mates can have access to your branch. There is no way to create a local branch for testing purposes.
On Git, you create a branch in your local repository. Optionally, this branch can be sent to remote repository, with an extra command for that.
svn copy 'https://svn.code.sf.net/p/tikiwiki/code/trunk' 'https://svn.code.sf.net/p/tikiwiki/code/branches/task-icon-picker' svn co 'https://svn.code.sf.net/p/tikiwiki/code/branches/task-icon-picker' tiki-icon-picker
git branch task-icon-picker git checkout task-icon-picker # The last command created a branch on local repository, # so, to send it to remote repository git push -u origin task-icon-picker
On SVN, if you have several changes on working space and try to commit that without specifying a file, all those changes will be committed.
But on Git, the behavior is different. You have to mark a file, folder or the entire working copy to be committed and then create the commit to save your changes.
svn add README.html svn ci -m '[NEW] HTML version for README'
git add README.html git commit -m '[NEW] HTML version for README' # But if there is no new files and the mission is commit all changes # just use the -a option git commit -a -m '[NEW] HTML version for README'
On SVN, when you want to discard changes on your working copy, you use the command revert to discard those changes and start again.
But on Git, the concept to discard changes is different. You take the content of your local repository and copy over files on you working copy. So the changes is discard. The revert on Git has other meaning.
The revert command on Git creates a commit that undo things of other commit. So, if you added a line on a file and committed that, the revert command will create another commit removing the line on that file.
echo 'My new line on README' >> README svn revert README
svn merge -c-63929 README
echo 'My new line on README' >> README git checkout README
git revert 4543a31466d48