<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sect1 SYSTEM "../../../dtd/dblite.dtd">
<sect1 id="tsvn-dug-import">
	<title>Importing Data Into A Repository</title>
	<indexterm>
		<primary>import</primary>
	</indexterm>
	<indexterm>
		<primary>repository</primary>
	</indexterm>
	<indexterm>
		<primary>add files to repository</primary>
	</indexterm>
	<?dbhh topicname="HIDD_IMPORT"?>
	<sect2 id="tsvn-dug-import-2">
		<title>Import</title>
		<indexterm>
			<primary>temporary files</primary>
		</indexterm>
		<para>
			If you are importing into an existing repository which already
			contains some projects, then the repository structure will already
			have been decided.
			If are importing data into a new repository then it is worth
			taking the time to think about how it will be organised. Read
			<xref linkend="tsvn-repository-layout"/> for further advice.
		</para>
		<para>
			This section describes the Git import command, which was designed
			for importing a directory hierarchy into the repository in one shot.
			Although it does the job, it has several shortcomings:
			<itemizedlist>
				<listitem>
					<para>
						There is no way to select files and folders to include,
						aside from using the global ignore settings.
					</para>
				</listitem>
				<listitem>
					<para>
						The folder imported does not become a working copy. You have
						to do a checkout to copy the files back from the server.
					</para>
				</listitem>
				<listitem>
					<para>
						It is easy to import to the wrong folder level in the repository.
					</para>
				</listitem>
			</itemizedlist>
			For these reasons we recommend that you do not use the import command
			at all but rather follow the two-step method described in
			<xref linkend="tsvn-dug-import-in-place"/>.
			But since you are here, this is how the basic import works ...
		</para>
		<para>
			Before you import your project into a repository you should:
			<orderedlist>
				<listitem>
					<para>
						Remove all files which are not needed to
						build the project (temporary files, files which are
						generated by a compiler e.g. *.obj, compiled
						binaries, ...)
					</para>
				</listitem>
				<listitem>
					<para>
						Organize the files in folders and
						sub-folders. Although it is possible to rename/move
						files later it is highly recommended to get your project's
						structure straight before importing!
					</para>
				</listitem>
			</orderedlist>
		</para>
		<para>
			Now select the top-level folder of your project
			directory structure in the windows explorer and
			<action>right click</action>
			to open the context menu. Select the command
			<menuchoice>
				<guimenu>TortoiseGit</guimenu>
				<guimenuitem>Import...</guimenuitem>
			</menuchoice>
			which brings up a dialog box:
			<figure id="tsvn-dug-import-dia-1">
				<title>The Import dialog</title>
				<graphic fileref="../images/Import.png"/>
			</figure>
		</para>
		<para>
			In this dialog you have to enter the URL of the repository location
			where you want to import your project.
			It is very important to realise that the local folder you are
			importing does not itself appear in the repository, only its content.
			For example if you have a structure:
<screen>
C:\Projects\Widget\source
C:\Projects\Widget\doc
C:\Projects\Widget\images
</screen>
			and you import <filename>C:\Projects\Widget</filename> into
			<systemitem class="url">http://mydomain.com/svn/trunk</systemitem>
			then you may be surprised to find that your subdirectories go
			straight into <literal>trunk</literal> rather than being in a
			<literal>Widget</literal> subdirectory. You need to specify the
			subdirectory as part of the URL,
			<systemitem class="url">http://mydomain.com/svn/trunk/Widget-X</systemitem>.
			Note that the import command will automatically create subdirectories
			within the repository if they do not exist.
		</para>
		<para>
			The import message is used as a log message.
		</para>
		<para>
			By default, files and folders which match the global-ignore patterns
			are <emphasis>not</emphasis> imported. To override this behaviour you can
			use the <guilabel>Include ignored files</guilabel> checkbox.
			Refer to <xref linkend="tsvn-dug-settings-main"/> for more information
			on setting a global ignore pattern.
		</para>
		<para>
			As soon as you press <guibutton>OK</guibutton> TortoiseGit imports the
			complete directory tree including all files into the repository.
			The project is now stored in the repository under version control.
			Please note that the folder you imported is <emphasis>NOT</emphasis>
			under version control! To get a version-controlled
			<firstterm>working copy</firstterm>
			you need to do a Checkout of the version you just imported.
			Or read on to find out how to import a folder in place.
		</para>
	</sect2>
	<sect2 id="tsvn-dug-import-in-place">
		<title>Import in Place</title>
		<indexterm>
			<primary>import in place</primary>
		</indexterm>
		<para>
			Assuming you already have a repository, and you want to add a new folder
			structure to it, just follow these steps:
			<orderedlist>
				<listitem>
					<para>
						Use the repository browser to create a new
						project folder directly in the repository.
					</para>
				</listitem>
				<listitem>
					<para>
						Checkout the new folder over the top of the folder you want to import.
						You will get a warning that the local folder is not empty.
						Now you have a versioned top level folder with unversioned content.
					</para>
				</listitem>
				<listitem>
					<para>
						Use
						<menuchoice>
							<guimenu>TortoiseGit</guimenu>
							<guimenuitem>Add...</guimenuitem>
						</menuchoice>
						on this versioned folder to add some or all of the content.
						You can add and remove files, set <literal>svn:ignore</literal>
						properties on folders and make any other changes you need to.
					</para>
				</listitem>
				<listitem>
					<para>
						Commit the top level folder, and you have a new versioned tree,
						and a local working copy, created from your existing folder.
					</para>
				</listitem>
			</orderedlist>
		</para>
	</sect2>
	<sect2 id="tsvn-dug-import-3">
		<title>Special Files</title>
		<indexterm>
			<primary>special files</primary>
		</indexterm>
		<para>
			Sometimes you need to have a file under version control which contains
			user specific data. That means you have a file which every developer/user
			needs to modify to suit his/her local setup. But versioning such a file
			is difficult because every user would commit his/her changes every
			time to the repository.
		</para>
		<para>
			In such cases we suggest to use <emphasis>template</emphasis> files.
			You create a file which contains all the data your developers
			will need, add that file to version control and let the developers
			check this file out. Then, each developer has to <emphasis>make a copy</emphasis>
			of that file and rename that copy. After that, modifying the copy
			is not a problem anymore.
		</para>
		<para>
			As an example, you can have a look at TortoiseGit's build script. It
			calls a file named <filename>TortoiseVars.bat</filename> which
			doesn't exist in the repository. Only the file
			<filename>TortoiseVars.tmpl</filename>.
			<filename>TortoiseVars.tmpl</filename> is the template file which
			every developer has to create a copy from and rename that file
			to <filename>TortoiseVars.bat</filename>. Inside that file, we added
			comments so that the users will see which lines they have to edit
			and change according to their local setup to get it working.
		</para>
		<para>
			So as not to disturb the users, we also added the file
			<filename>TortoiseVars.bat</filename> to the ignore list of its
			parent folder, i.e. we've set the Git property
			<literal>svn:ignore</literal> to include that filename.
			That way it won't show up as unversioned on every commit.
		</para>
	</sect2>
	<sect2 id="tsvn-dug-import-4">
		<title>Referenced Projects</title>
		<indexterm>
			<primary>external repositories</primary>
		</indexterm>
		<indexterm>
			<primary>externals</primary>
		</indexterm>
		<para>
			Sometimes it is useful to construct a working copy that is made out
			of a number of different checkouts. For example, you may want different
			subdirectories to come from different locations in a repository, or
			perhaps from different repositories altogether. 
			If you want every user to have the same layout, you can define the
			<literal>svn:externals</literal> properties.
		</para>
		<para>
			Let's say you check out a working copy of
			<filename>/project1</filename> to
			<filename>D:\dev\project1</filename>.
			Select the folder <filename>D:\dev\project1</filename>,
			<action>right click</action> and choose 
			<menuchoice>
				<guimenu>Windows Menu</guimenu>
				<guimenuitem>Properties</guimenuitem>
			</menuchoice>
			from the context menu. 
			The Properties Dialog comes up. Then go to the Git tab.
			There, you can set properties. Click <guibutton>Add...</guibutton>.
			Select the <literal>svn:externals</literal> property from the
			combobox and write in the edit box the repository URL in the format
			<literal>name url</literal>
			or if you want to specify a particular revision,
			<literal>name -rREV url</literal>
			You can add multiple external projects, 1 per line.
			Note that URLs must be properly escaped or they will
			not work. For example you must replace each space with
			<literal>%20</literal>. Note that it is not possible to use
			folder names with spaces in them.
			Suppose that you have set these properties on
			<filename>D:\dev\project1</filename>:
<screen>
sounds   http://sounds.red-bean.com/repos
quick_graphs  http://graphics.red-bean.com/repos/fast%20graphics
skins/toolkit -r21 http://svn.red-bean.com/repos/skin-maker
</screen>
			Now click <guibutton>Set</guibutton> and commit your changes.
			When you (or any other user) update your working copy, Git
			will create a sub-folder 
			<filename>D:\dev\project1\sounds</filename> and checkout the sounds
			project, another sub-folder <filename>D:\dev\project1\quick graphs</filename>
			containing the graphics project, and finally a nested sub-folder
			<filename>D:\dev\project1\skins\toolkit</filename> containing
			revision 21 of the skin-maker project.
		</para>
		<tip>
			<para>
				You should strongly consider using explicit revision numbers
				in all of your externals definitions, as described above.
				Doing so means
				that you get to decide when to pull down a different snapshot
				of external information, and exactly which snapshot to pull.
				Besides the common sense aspect of not being surprised by
				changes to third-party repositories that you might not have
				any control over, using explicit revision numbers also means
				that as you backdate your working copy to a previous
				revision, your externals definitions will also revert to the
				way they looked in that previous revision, which in turn means
				that the external working copies will be updated to match they
				way <emphasis>they</emphasis> looked back when your repository was
				at that previous revision.  For software projects, this could
				be the difference between a successful and a failed build of
				an older snapshot of your complex code base.
			</para>
		</tip>
		<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>
			If you use absolute URLs in <literal>svn:externals</literal>
			definitions and you have to relocate your working copy (i.e.,
			if the URL of your repository changes), then your externals
			won't change and might not work anymore.
		</para>
		<para>
			To avoid such problems, Git clients version 1.5 and
			higher support relative external URLs. Four different methods
			of specifying a relative URL are supported.
			In the following examples, assume we have two repositories: one at
			<systemitem class="url">http://example.com/svn/repos-1</systemitem>
			and another at
			<systemitem class="url">http://example.com/svn/repos-2</systemitem>.
			We have a checkout of
			<systemitem class="url">http://example.com/svn/repos-1/project/trunk</systemitem>
			into <filename>C:\Working</filename> and the <literal>svn:externals</literal>
			property is set on trunk.
		</para>
		<variablelist>
			<varlistentry>
				<term>Relative to parent directory</term>
				<listitem>
					<para>
						These URLs always begin with the string <literal>../</literal>
						for example:
<screen>
../../widgets/foo  common/foo-widget
</screen>
						This will extract
						<systemitem class="url">http://example.com/svn/repos-1/widgets/foo</systemitem>
						into
						<filename>C:\Working\common\foo-widget</filename>.
					</para>
					<para>
						Note that the URL is relative to the URL of the directory with the
						<literal>svn:externals</literal> property, not to the directory where
						the external is written to disk.
					</para>
				</listitem>
			</varlistentry>
			<varlistentry>
				<term>Relative to repository root</term>
				<listitem>
					<para>
						These URLs always begin with the string <literal>^/</literal>
						for example:
<screen>
^/widgets/foo  common/foo-widget
</screen>
						This will extract
						<systemitem class="url">http://example.com/svn/repos-1/widgets/foo</systemitem>
						into
						<filename>C:\Working\common\foo-widget</filename>.
					</para>
					<para>
						You can easily refer to other repositories with the same
						<literal>SVNParentPath</literal> (a common directory holding
						several repositories). For example:
<screen>
^/../repos-2/hammers/claw  common/claw-hammer
</screen>
						This will extract
						<systemitem class="url">http://example.com/svn/repos-2/hammers/claw</systemitem>
						into
						<filename>C:\Working\common\claw-hammer</filename>.
					</para>
				</listitem>
			</varlistentry>
			<varlistentry>
				<term>Relative to scheme</term>
				<listitem>
					<para>
						URLs beginning with the string <literal>//</literal> copy
						only the scheme part of the URL. This is useful when the same hostname
						must the accessed with different schemes depending upon network location;
						e.g. clients in the intranet use <systemitem class="url">http://</systemitem>
						while external clients use <systemitem class="url">svn+ssh://</systemitem>.
						For example:
<screen>
//example.com/svn/repos-1/widgets/foo  common/foo-widget
</screen>
						This will extract
						<systemitem class="url">http://example.com/svn/repos-1/widgets/foo</systemitem>
						or
						<systemitem class="url">svn+ssh://example.com/svn/repos-1/widgets/foo</systemitem>
						depending on which method was used to checkout
						<filename>C:\Working</filename>.
					</para>
				</listitem>
			</varlistentry>
			<varlistentry>
				<term>Relative to the server's hostname</term>
				<listitem>
					<para>
						URLs beginning with the string <literal>/</literal> copy
						the scheme and the hostname part of the URL, for example:
<screen>
/svn/repos-1/widgets/foo  common/foo-widget
</screen>
						This will extract
						<systemitem class="url">http://example.com/svn/repos-1/widgets/foo</systemitem>
						into
						<filename>C:\Working\common\foo-widget</filename>.
						But if you checkout your working copy from another server at
						<systemitem class="url">svn+ssh://another.mirror.net/svn/repos-1/project1/trunk</systemitem>
						then the external reference will extract
						<systemitem class="url">svn+ssh://another.mirror.net/svn/repos-1/widgets/foo</systemitem>.
					</para>
				</listitem>
			</varlistentry>
		</variablelist>
		<para>
			If you need more information how TortoiseGit
			handles Properties read <xref linkend="tsvn-dug-propertypage"/>.
		</para>
		<para>
			To find out about different methods of accessing common sub-projects
			read <xref linkend="tsvn-howto-common-projects"/>.
		</para>
	</sect2>
</sect1>
