We use a version control software called Subversion. With
this we can check out repositories, create branches, commit code changes, and
do many other cool things. We don’t use the command line to interact with
Subversion, rather we use TortoiseSVN, which allows us to use Subversion
through the Windows file system. Before starting this guide, ensure you have
TortoiseSVN installed on your machine.
Checkout
First, we want to check out a repository. For this
example, lets check out the “internal” repo. Navigate to C:/java/codebase, right
click anywhere inside the file, and click “SVN Checkout.” Click the button
containing three dots to the right of the “URL of Repository” field. In the
“URL” field at the top, go to http://sourcecontrol.fullcount.net/repos/internal
and hit enter. Then, hit OK.
The checkout directory should automatically update to
“C:\java\codebase\internal”. If it hasn’t, update that now, ensure the Checkout
Depth is “Fully Recursive”, and hit “OK”. You should see a new file called
“internal” in the codebase file. Navigate to internal/trunk to ensure that
trunk has contents.
Update
Once repos are checked out, we need to make sure we keep
them updated. To do this, right click on the trunk file of the repo you want to
update and select “SVN Update…” In the internal repo, make sure you right click
on the project(s) you want to update, like at-fullcount-model (tip: you can
select multiple projects and update them all at once).
This pulls down all the changes other developers have
made to the branch you are currently in.
Branch
“trunk” is your main copy of your local repository.
Generally, you shouldn’t commit directly to trunk; you should create a branch
and commit code changes to that.
Creating a branch can be different depending on what you
want to make a branch of. For any projects in the “internal” repo, you’ll want
to right click on the file of the project you want to make a branch of (i.e.
at-fullcount-model, POSWebApplication, etc.), and select SVN Update. Next,
right click on the project and select TortoiseSVN -> Branch/Tag… On this
dialog, ensure the “from” URL shown is the trunk version of the project. Click
on the button with three dots to the right of the “To Path” field. Navigate to
the “branches” folder and find the folder for the project you want to branch
and click on it. Click OK.
For non-internal repos, you’ll do the same thing, but
you’ll right click on the “trunk” folder instead.
At this point, you should see that folder in the “To
path” field. Now we want to name the branch for our task. We always name it
after the Redmine task we are working on, in the format of:
<Redmine Issue Number>-<Short Description>
For instance, if the Redmine number is 1234, and the task
is called “Update Documentation for the New Name Field in the Customers Page”,
I might name the branch:
1234-update-docs-customer-page
In the To Path field, enter a “/” and then your branch
name. Then, in the Log Message field, you should enter the type of your Redmine
task, number of your task, and the title of the task like the following:
Feature #1234 - Update Documentation for the New Name
Field in the Customers Page
Double check your “From” URL and “Destination” URL are
correct and hit OK, and you’ve created the branch.
Switch
In order to commit to a branch, we need to switch to that
branch. Right click on the project, click TortoiseSVN -> Switch…
Click on the button to the right of the “To Path” field,
find your branch, and click OK. Ensure that the Destination URL is correct and
hit OK.
Commit
After completing code changes for a task, you will need
to get those changes to your task’s branch. To do this, we will need to use the
SVN Commit… command. In File Explorer, right click the project you want to
commit changes to and select SVN Commit. This dialog will show you all the
files you’ve made changes to. Deselect any files that don’t need to be
committed with the solution to your task (and ALWAYS deselect the jndi file).
For the files that do need to be committed, double-click on one of them. This
will show you the changes you’ve made to this file. Verify that your changes
are correct for each file. In the Message text box, enter in the type of
redmine task, the number of the redmine task, and then enter in a meaningful,
concise summary of what your changes do. Here are some examples:
Feature
#1234 – Added Delete button to reservations table
Bug
#8675 – Fixed infinite loading bar on transactions table
Finally, verify that the “Commit to” URL is pointing to
your branch and click ok. This saves your local changes into your branch.
Unlike Git, there is no need to do a “push” command.
NOTE: If you add a new file to a project, it won’t
immediately show up in the Commit dialog. In order to see it, you have to check
“Show unversioned files” and then you can select the file and commit it.
A common question to ask is, “How often should I be
committing?” This is a difficult question to answer without being extremely
vague. Don’t commit every line change individually, but you should also avoid
committing massive amounts of changes at once. However, the problem is rarely
committing too much, and more often not committing enough.
As soon as you get a “complete thought” of code complete,
you should commit. This could be a method, a small feature, or as small as
fixing a typo. You won’t be punished if you don’t commit often enough, but it
will make the job of the code reviewer easier. Committing often also allows you
to easily revert code changes that don’t work as we initially envisioned.
Merge
Occasionally, you should merge in changes from trunk to
your branch. First, you should commit any changes you’ve made (or revert
changes you don’t need). Next, right click the trunk file of your repo (except
the internal repo, where you’ll right click the project you want to update),
and select TortoiseSVN -> Merge…
Select “Merge a range of revisions” and click Next.
Ensure the “URL to merge from” is the trunk version of your branch. Under
“Revision range to merge,” select “specific range” and click Show Log. This
dialog will show you all the commits to the trunk branch that have been made
since the branch has been created. Check all the entries that aren’t grayed out
(as shown below) and click ok (Grayed out entries are ones that you have
already merged into you branch)
You should see the revision numbers load into the field
to the left of the Show log button. Click next, then click “Test merge.” This
will tell you if the merge will be successful, and if there will be merge
conflicts. Most of the time there won’t be any errors/conflicts, but it is
always good to check. Click OK to close the dialog, then click Merge.
This merge will make changes to your local copy, but it
won’t make any changes to your branch. In order to get these changes to your
branch, you have to commit the changes you just merged in. Right click the
project, click SVN Commit, and select all the changes you just merged in.
You should notice there are one or two files that look
like folders (maybe labeled “trunk” or “src”). Subversion made these changes so
it can track which revisions have been merged into this branch. Make sure you
select these.
The message should be a little different than our normal
commit. We won’t include any information on the redmine task. Just say
something simple, like “Merge from trunk.” Ensure your “Commit to” URL is your
branch’s URL and click OK.
Merge Conflicts
Occasionally, when merging in changes from trunk, you’ll
run into a merge conflict. Merge Conflicts, although they may seem scary, are
nothing to worry about. Most of the time this is caused by someone else editing
the same line that you have, and Subversion is asking you for help to figure
out what changes you want to keep. When going through the Merging process,
after hitting “Test merge” you may get a dialog like the following:
Subversion is warning you that these files may result in
a conflict when merged. Generally, these “Conflicted (maybe)” files always
result in a merge conflict. After merging in these changes to our working copy
we will get dialogs for each merge conflict, as Subversion isn’t sure how to
handle these changes:
We have a lot of options here, but the most common one
you will use is the “Edit” option on bottom. This allows you to select each
line to determine what it should be:
There are three versions of the file here: the incoming
file from the merge (Theirs), your working copy of the file (Mine), and the
resulting Merged file. The red lines are where there is a merge conflict, as
the incoming file and our working copy modified the same line.
You can fix this in many ways. First, select some
conflicted lines and right click them. You have many ways to proceed:
Accept
the changes from the incoming file, completely removing your local changes
Accept
the changes from your working copy, completely ignoring the changes from
the incoming file
Use
“their” text block first, which will put their changes in the file first,
followed by your changes on the next line.
Use
“mine” text block first, which will put your changes in the file first,
followed by their changes on the next line.
You need to determine the best way to proceed for the
situation. Many times you will want to keep your local changes and accept the
incoming changes (either using the “Use ‘Their’ text block first” or “Use
‘Mine’ text block first”), but this isn’t always the case. If you’re having
trouble deciding, ask a fellow developer for help. After you make your
decision, make sure you save with Ctrl + S and hit the “Mark as Resolved”
button.
This will bring you back to the “Merge conflict
discovered in file XXXX” dialog. The “Mark as Resolved” option should no longer
be grayed out. Click it to mark the file as resolved.
Sometimes you will run into a file where editing line by
line isn’t an option:
Although we technically have an “Edit” option, when we
click it, we just get an error. So, what do we do? For .jasper files, it is
good practice to “Accept incoming”, commit the changes, then go into Jaspersoft
Studio and compile the report again. This will ensure the compiled file has the
incoming changes and any changes you’ve made in your branch.
In the end, your Merged Finished dialog may look like the
following:
Even though we’ve resolved the conflict in the
ItemCodesList, its still marked as “Conflicted.” However, if we double click
that line, we don’t receive any popup, so we know its actually resolved (if it
wasn’t resolved, on double click the “Merge conflict discovered in file XXXX”
dialog would appear). Click OK, and commit those changes as stated in the
“Merge” section.
Reverting Changes
Occasionally, you’ll make changes to a file, but after a
little while you’ll no longer need those changes. You can just delete
the new code/replace code you deleted, but you can also use SVN Revert to
easily revert that file back to the state it is on your remote branch. There
are multiple ways to revert file changes:
Find
the file in your file system, right click it, and select “Revert.” A
dialog will pop up with the file(s) you’re about to revert. Confirm you
want to revert these file(s), and hit “OK” to revert the file(s) to the
state they are on the remote branch you currently have checked out.
You
can also revert changes from the “Commit” dialog. Right click on the
project file and hit “SVN Commit.” Find the file you want to revert
changes in, right click it and click “Revert.” A confirmation dialog will
pop up, select “Revert” to revert the changes on the file.
You
can also revert changes by line in the Diff dialog of the file.
Open the Diff view of the file (either by using SVN Commit -> Double
clicking the file, or by finding the file in File Explorer, right clicking
and select TortoiseSVN -> Diff), select any number of lines that have
changed in the “Working Base” version of the file, right click and select
“Use this text block.” To save your changes, hit Ctrl + S.
You can also revert commits to a branch. Right click the
project folder and select “TortoiseSVN -> Show Log.” This shows you all the
commits made to the branch you currently have checked out. Right click on a
commit and you will see two options we are interested in:
Revert
to this Revision
This
will revert all the changes from the commits after the selected
commit.
Revert
Changes from this Revision
This
will only revert the changes from the selected commit.
After either of these options are selected, changes will
be made to your local copy only. This means, to revert these changes on
your remote branch, you must commit these local changes to that branch. Check
the “Commit” section on how to commit to a branch.