<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE appendix SYSTEM "../../dtd/dblite.dtd">
<appendix id="tsvn-howto" xmlns:xi="http://www.w3.org/2001/XInclude">
	<title>How Do I...</title>
	<simplesect>
		<para>
			This appendix contains solutions to problems/questions you might
			have when using TortoiseGit.
		</para>
	</simplesect>
	<sect1 id="tsvn-howto-move">
		<title>Move/copy a lot of files at once</title>
		<indexterm>
			<primary>moving</primary>
		</indexterm>
		<indexterm>
			<primary>rename</primary>
		</indexterm>
		<indexterm>
			<primary>reorganize</primary>
		</indexterm>
		<para>
			Moving/Copying single files can be done by using
			<menuchoice>
				<guimenu>TortoiseGit</guimenu>
				<guimenuitem>Rename...</guimenuitem>
			</menuchoice>.
			But if you want to move/copy a lot of files, this way is just
			too slow and too much work.
		</para>
		<para>
			The recommended way is by <action>right-dragging</action> the files to
			the new location. Simply <action>right-click</action> on the files you want
			to move/copy without releasing the mouse button. Then drag the files
			to the new location and release the mouse button. A context menu will appear
			where you can either choose
			<menuchoice>
				<guimenu>Context Menu</guimenu>
				<guimenuitem>SVN Copy versioned files here</guimenuitem>
			</menuchoice>.
			or
			<menuchoice>
				<guimenu>Context Menu</guimenu>
				<guimenuitem>SVN Move versioned files here</guimenuitem>
			</menuchoice>.
		</para>
		<para>
			<mediaobject>
				<videoobject>
					<videodata fileref="images/svn_move.swf" format="SWF" contentwidth="590" contentdepth="290"/>
				</videoobject>
				<imageobject>
					<imagedata fileref="images/svn_move.png"/>
				</imageobject>
			</mediaobject>
		</para>
	</sect1>
	<sect1 id="tsvn-howto-minlogmsgsize">
		<title>Force users to enter a log message</title>
		<indexterm>
			<primary>log message</primary>
		</indexterm>
		<indexterm>
			<primary>commit message</primary>
		</indexterm>
		<indexterm>
			<primary>empty message</primary>
		</indexterm>
		<para>
			There are two ways to prevent users from committing with an empty
			log message. One is specific to TortoiseGit, the other works for
			all Git clients, but requires access to the server directly.
		</para>
		<sect2 id="tsvn-howto-minlogsize-hookscript">
			<title>Hook-script on the server</title>
			<para>
				If you have direct access to the repository server, you can install
				a pre-commit hook script which rejects all commits with an empty
				or too short log message.
			</para>
			<para>
				In the repository folder on the server, there's a sub-folder
				<filename>hooks</filename>
				which contains some example hook scripts you can use. The file
				<filename>pre-commit.tmpl</filename>
				contains a sample script which will reject commits if no log message
				is supplied, or the message is too short.
				The file also contains comments on how to install/use this script.
				Just follow the instructions in that file.
			</para>
			<para>
				This method is the recommended way if your users also use other
				Git clients than TortoiseGit. The drawback is that the commit
				is rejected by the server and therefore users will get an error
				message. The client can't know before the commit that it will be
				rejected. If you want to make TortoiseGit have the <guibutton>OK</guibutton>
				button disabled until the log message is long enough
				then please use the method described below.
			</para>
		</sect2>
		<sect2 id="tsvn-howto-minlogsize-projectproperties">
			<title>Project properties</title>
			<para>
				TortoiseGit uses properties to control some of its features. One of those
				properties is the <literal>tsvn:logminsize</literal> property.
			</para>
			<para>
				If you set that property on a folder, then TortoiseGit will disable the
				<guibutton>OK</guibutton> button in all commit dialogs until the user has
				entered a log message with at least the length specified in the property.
			</para>
			<para>
				For detailed information on those project properties, please refer to
				<xref linkend="tsvn-dug-propertypage"/>
			</para>
		</sect2>
	</sect1>
	<sect1 id="tsvn-howto-selective-update">
		<title>Update selected files from the repository</title>
		<indexterm>
			<primary>update</primary>
		</indexterm>
		<para>
			Normally you update your working copy using
			<menuchoice>
				<guimenu>TortoiseGit</guimenu>
				<guimenuitem>Update</guimenuitem>
			</menuchoice>.
			But if you only want to pick up some new files that a colleague has added
			without merging in any changes to other files at the same time, you need
			a different approach.
		</para>
		<para>
			Use
			<menuchoice>
				<guimenu>TortoiseGit</guimenu>
				<guimenuitem>Check for Modifications</guimenuitem>
			</menuchoice>.
			and click on <guibutton>Check repository</guibutton> to see what has changed
			in the repository. Select the files you want to update locally, then use
			the context menu to update just those files.
		</para>
	</sect1>
	<sect1 id="tsvn-howto-rollback">
		<title>Roll back (Undo) revisions in the repository</title>
		<indexterm>
			<primary>rollback</primary>
		</indexterm>
		<indexterm>
			<primary>revert</primary>
		</indexterm>
		<indexterm>
			<primary>undo commit</primary>
		</indexterm>
		<indexterm>
			<primary>undo change</primary>
		</indexterm>
		<sect2 id="tsvn-howto-rollback-log">
			<title>Use the revision log dialog</title>
			<para>
				The easiest way to revert the changes from a single revision,
				or from a range of revisions,
				is to use the revision log dialog.
				This is also the method to use of you want to discard recent
				changes and make an earlier revision the new HEAD.
			</para>
			<orderedlist>
				<listitem>
					<para>
						Select the file or folder in which you need to revert
						the changes. If you want to revert all changes, this
						should be the top level folder.
					</para>
				</listitem>
				<listitem>
					<para>
						Select
						<menuchoice>
							<guimenu>TortoiseGit</guimenu>
							<guimenuitem>Show Log</guimenuitem>
						</menuchoice>
						to display a list of revisions. You may need to use
						<guibutton>Show All</guibutton> or
						<guibutton>Next 100</guibutton>
						to show the revision(s) you are interested in.
					</para>
				</listitem>
				<listitem>
					<para>
						Select the revision you wish to revert. If you want
						to undo a range of revisions, select the first one
						and hold the <keycap>Shift</keycap> key while selecting the last one.
						Note that for multiple revisions, the range must be
						unbroken with no gaps.
						<action>Right click</action> on the selected revision(s),
						then select
						<menuchoice>
							<guimenu>Context Menu</guimenu>
							<guimenuitem>Revert changes from this revision</guimenuitem>
						</menuchoice>.
					</para>
				</listitem>
				<listitem>
					<para>
						Or if you want to make an earlier revision the new HEAD revision,
						<action>right click</action> on the selected revision,
						then select
						<menuchoice>
							<guimenu>Context Menu</guimenu>
							<guimenuitem>Revert to this revision</guimenuitem>
						</menuchoice>.
						This will discard <emphasis>all</emphasis> changes after
						the selected revision.
					</para>
				</listitem>
			</orderedlist>
			<para>
				You have reverted the changes within your working copy.
				Check the results, then commit the changes.
			</para>
		</sect2>
		<sect2 id="tsvn-howto-rollback-merge">
			<title>Use the merge dialog</title>
			<para>
				To undo a larger range of revisions, you can use the Merge dialog.
				The previous method uses merging behind the scenes; this method
				uses it explicitly.
			</para>
			<orderedlist>
				<listitem>
					<para>
						In your working copy select
						<menuchoice>
							<guimenu>TortoiseGit</guimenu>
							<guimenuitem>Merge</guimenuitem>
						</menuchoice>.
					</para>
				</listitem>
				<listitem>
					<para>
						In the <guilabel>From:</guilabel> field enter the full
						folder URL of the branch or tag containing the changes
						you want to revert in your working copy. This should come
						up as the default URL.
					</para>
				</listitem>
				<listitem>
					<para>
						In the <guilabel>From Revision</guilabel> field enter the
						revision number that you are currently at. If you are
						sure there is no-one else making changes, you can use the
						HEAD revision.
					</para>
				</listitem>
				<listitem>
					<para>
						make sure the <guilabel>Use "From:" URL</guilabel>
						checkbox is checked.
					</para>
				</listitem>
				<listitem>
					<para>
						In the <guilabel>To Revision</guilabel> field enter the
						revision number that you want to revert to, namely the one
						<emphasis>before</emphasis> the first revision to be reverted.
					</para>
				</listitem>
				<listitem>
					<para>
						Click <guibutton>OK</guibutton> to complete the merge.
					</para>
				</listitem>
			</orderedlist>
			<para>
				You have reverted the changes within your working copy.
				Check the results, then commit the changes.
			</para>
		</sect2>
		<sect2 id="tsvn-howto-rollback-dumpload">
			<title>Use <literal>svndumpfilter</literal></title>
			<para>
				Since TortoiseGit never loses data, your <quote>rolled back</quote>
				revisions still exist as intermediate revisions in the repository. Only 
				the HEAD revision was changed to a previous state.
				If you want to make revisions disappear completely from your
				repository, erasing all trace that they ever existed, you have
				to use more extreme measures. Unless there is a really good reason
				to do this, it is <emphasis>not recommended</emphasis>. One
				possible reason would be that someone committed a confidential
				document to a public repository.
			</para>
			<para>
				The only way to remove data from the repository is to use the
				Git command line tool <literal>svnadmin</literal>.
				You can find a description of how this works in the
				<ulink url="http://svnbook.red-bean.com/en/1.5/svn.reposadmin.maint.html">
					<citetitle>Repository Maintenance</citetitle>
				</ulink>.
			</para>
		</sect2>
	</sect1>
	<sect1 id="tsvn-howto-compare">
		<title>Compare two revisions of a file or folder</title>
		<indexterm>
			<primary>compare files</primary>
		</indexterm>
		<indexterm>
			<primary>compare folders</primary>
		</indexterm>
		<indexterm>
			<primary>changes</primary>
		</indexterm>
		<para>
			If you want to compare two revisions in an item's history,
			for example revisions 100 and 200 of the same file, just use
			<menuchoice>
				<guimenu>TortoiseGit</guimenu>
				<guimenuitem>Show Log</guimenuitem>
			</menuchoice>
			to list the revision history for that file. Pick the two revisions
			you want to compare then use
			<menuchoice>
				<guimenu>Context Menu</guimenu>
				<guimenuitem>Compare Revisions</guimenuitem>
			</menuchoice>.
		</para>
		<para>
			If you want to compare the same item in two different trees,
			for example the trunk and a branch, you can use the repository
			browser to open up both trees, select the file in both places,
			then use
			<menuchoice>
				<guimenu>Context Menu</guimenu>
				<guimenuitem>Compare Revisions</guimenuitem>
			</menuchoice>.
		</para>
		<para>
			If you want to compare two trees to see what has changed,
			for example the trunk and a tagged release, you can use
			<menuchoice>
				<guimenu>TortoiseGit</guimenu>
				<guimenuitem>Revision Graph</guimenuitem>
			</menuchoice>
			Select the two nodes to compare, then use
			<menuchoice>
				<guimenu>Context Menu</guimenu>
				<guimenuitem>Compare HEAD Revisions</guimenuitem>
			</menuchoice>.
			This will show a list of changed files, and you can then select
			individual files to view the changes in detail.
			You can also export a tree structure containing all the changed
			files, or simply a list of all changed files.
			Read <xref linkend="tsvn-dug-compare-revs"/> for more information.
			Alternatively use
			<menuchoice>
				<guimenu>Context Menu</guimenu>
				<guimenuitem>Unified Diff of HEAD Revisions</guimenuitem>
			</menuchoice>
			to see a summary of all differences, with minimal context.
		</para>
	</sect1>
	<sect1 id="tsvn-howto-common-projects">
		<title>Include a common sub-project</title>
		<indexterm>
			<primary>common projects</primary>
		</indexterm>
		<indexterm>
			<primary>externals</primary>
		</indexterm>
		<indexterm>
			<primary>vendor projects</primary>
		</indexterm>
		<para>
			Sometimes you will want to include another project within
			your working copy, perhaps some library code. You don't
			want to make a duplicate of this code in your repository
			because then you would lose connection with the original
			(and maintained) code. Or maybe you have several projects
			which share core code. There are at least 3 ways of dealing
			with this.
		</para>
		<sect2 id="tsvn-howto-common-externals">
			<title>Use svn:externals</title>
			<para>
				Set the <literal>svn:externals</literal> property for a folder
				in your project. This property consists of one or more lines;
				each line has the name of a sub-folder which you want to use
				as the checkout folder for common code, and the repository URL
				that you want to be checked out there. For full details
				refer to <xref linkend="tsvn-dug-import-4"/>.
			</para>
			<para>
				Commit the new folder. Now when you update, Git
				will pull a copy of that project from its repository
				into your working copy. The sub-folders will be created
				automatically if required.
				Each time you update your main working copy, you will also
				receive the latest version of all external projects.
			</para>
			<para>
				If the external project is in the same repository, any changes
				you make there there will be included in the commit list when
				you commit your main project.
			</para>
			<para>
				If the external project is in a different repository, any
				changes you make to the external project will be notified
				when you commit the main project, but you have to commit
				those external changes separately.
			</para>
			<para>
				Of the three methods described, this is the only one which needs
				no setup on the client side. Once externals are specified in
				the folder properties, all clients will get populated folders
				when they update.
			</para>
		</sect2>
		<sect2 id="tsvn-howto-common-nested">
			<title>Use a nested working copy</title>
			<para>
				Create a new folder within your project to contain the
				common code, but do not add it to Git
			</para>
			<para>
				Select
				<menuchoice>
					<guimenu>TortoiseGit</guimenu>
					<guimenuitem>Checkout</guimenuitem>
				</menuchoice>
				for the new folder and checkout a copy of the common
				code into it. You now have a separate working copy nested
				within your main working copy.
			</para>
			<para>
				The two working copies are independent. When you commit
				changes to the parent, changes to the nested WC are ignored.
				Likewise when you update the parent, the nested WC is not updated.
			</para>
		</sect2>
		<sect2 id="tsvn-howto-common-location">
			<title>Use a relative location</title>
			<para>
				If you use the same common core code in several projects,
				and you do not want to keep multiple working copies of it
				for every project that uses it, you can just check it out
				to a separate location which is related to all the other
				projects which use it. For example:
<screen>
C:\Projects\Proj1
C:\Projects\Proj2
C:\Projects\Proj3
C:\Projects\Common
</screen>
				and refer to the common code using a relative path, eg.
				<filename>..\..\Common\DSPcore</filename>.
			</para>
			<para>
				If your projects are scattered in unrelated locations you
				can use a variant of this, which is to put the common
				code in one location and use drive letter substitution to
				map that location to something you can hard code in your
				projects, eg. Checkout the common code to
				<filename>D:\Documents\Framework</filename> or
				<filename>C:\Documents and Settings\{login}\My Documents\framework</filename>
				then use
<screen>
SUBST X: "D:\Documents\framework"
</screen>
				to create the drive mapping used in your source code.
				Your code can then use absolute locations.
<screen>
#include "X:\superio\superio.h"
</screen>
			</para>
			<para>
				This method will only work in an all-PC environment,
				and you will need to document the required drive mappings
				so your team know where these mysterious files are.
				This method is strictly for use in closed development environments,
				and not recommended for general use.
			</para>
		</sect2>
	</sect1>
	<sect1 id="tsvn-howto-repo-shortcut">
		<title>Create a shortcut to a repository</title>
		<indexterm>
			<primary>shortcut</primary>
		</indexterm>
		<para>
			If you frequently need to open the repository browser at a
			particular location, you can create a desktop shortcut
			using the automation interface to TortoiseProc. Just
			create a new shortcut and set the target to:
<screen>
TortoiseProc.exe /command:repobrowser /path:"url/to/repository"
</screen>
			Of course you need to include the real repository URL.
		</para>
	</sect1>
	<sect1 id="tsvn-howto-unversion">
		<title>Ignore files which are already versioned</title>
		<indexterm>
			<primary>unversion</primary>
		</indexterm>
		<indexterm>
			<primary>remove versioning</primary>
		</indexterm>
		<indexterm>
			<primary>detach from repository</primary>
		</indexterm>
		<para>
			If you accidentally added some files which should have been
			ignored, how do you get them out of version control without
			losing them? Maybe you have your own IDE configuration file
			which is not part of the project, but which took you a long
			time to set up just the way you like it.
		</para>
		<para>
			If you have not yet committed the add, then all you have to do
			is use
			<menuchoice>
				<guimenu>TortoiseGit</guimenu>
				<guimenuitem>Revert...</guimenuitem>
			</menuchoice>
			to undo the add. You should then add the file(s) to the ignore
			list so they don't get added again later by mistake.
		</para>
		<para>
			If the files are already in the repository, you have to do
			a little more work.
			<orderedlist>
				<listitem>
					<para>
						Hold the <keycap>Shift</keycap> key to get the extended
						context menu and use
						<menuchoice>
							<guimenu>TortoiseGit</guimenu>
							<guimenuitem>Delete (keep local)</guimenuitem>
						</menuchoice>
						to mark the file/folder for deletion from the repository
						without losing the local copy.
					</para>
				</listitem>
				<listitem>
					<para>
						<menuchoice>
							<guimenu>TortoiseGit</guimenu>
							<guimenuitem>Commit</guimenuitem>
						</menuchoice>
						the parent folder.
					</para>
				</listitem>
				<listitem>
					<para>
						Add the file/folder to the ignore list so you don't get
						into the same trouble again.
					</para>
				</listitem>
			</orderedlist>
		</para>
	</sect1>
	<sect1 id="tsvn-howto-unversion-wc">
		<title>Unversion a working copy</title>
		<para>
			If you have a working copy which you want to convert back to
			a plain folder tree without the <literal>.svn</literal>
			directories, you can simply export it to itself. Read
			<xref linkend="tsvn-dug-export-unversion"/> to find out how.
		</para>
	</sect1>
	<sect1 id="tsvn-howto-remove-wc">
		<title>Remove a working copy</title>
		<para>
			If you have a working copy which you no longer need, how do you
			get rid of it cleanly? Easy - just delete it in Windows Explorer!
			Working copies are private local entities, and they are self-contained.
		</para>
	</sect1>
</appendix>
