Subversion, svn: Difference between revisions

From Andreida
No edit summary
 
(21 intermediate revisions by the same user not shown)
Line 1: Line 1:
[[Deciding which Source Management Tool to use?]]
* [[Deciding which Source Management Tool to use]]


* Here the most important link: [https://subversion.apache.org/ Apache® Subversion®]
* Here the most important link: [https://subversion.apache.org/packages.html Subversion]
* Here is the 2nd most important link: [https://svnbook.red-bean.com/ the documentation]
* Here is the 2nd most important link: [https://svnbook.red-bean.com/ the documentation]

But if you'd like to use Tortoise (gui + command line):
* [https://tortoisesvn.net/downloads.html Tortoise]
* [https://tortoisesvn.net/support.html Tortoise+svn Manual]




Line 15: Line 19:
You need a working svn, so with Debian you would do something like
You need a working svn, so with Debian you would do something like
apt-get install subversion
apt-get install subversion
while with Windows you get one of the [https://subversion.apache.org/packages.html#windows Windows binaries]:
while with Windows you either use winget
winget install TortoiseSVN

or get one of the [https://subversion.apache.org/packages.html#windows Windows binaries]:
* SilkSVN for just the command line, as far as I know
* SilkSVN for just the command line, as far as I know
* TortoiseSVN to get a graphical interface in your explorer (or [https://www.ghisler.com/ Total Commander]), command line still available but has to be selected during install (I ALWAYS install the command line too, some things are just more understandable when done on the command line)
* TortoiseSVN to get a graphical interface in your explorer (or [https://www.ghisler.com/ Total Commander]), command line still available but has to be selected during install (I ALWAYS install the command line too, some things are just more understandable when done on the command line)
Line 68: Line 75:
branches
branches
tags
tags
* Create this structure in the repository:
* Create this structure in the repository: (consider to not use "--parents" so you find typing errors)
svn mkdir file:///d:/data/repos/svn/tutorials/ue4/GDPwUE/trunk -m "creating trunk dir for GDPwUE" --parents
svn mkdir file:///d:/data/repos/svn/tutorials/ue4/GDPwUE/trunk -m "creating trunk dir for GDPwUE" --parents
svn mkdir file:///d:/data/repos/svn/tutorials/ue4/GDPwUE/branches -m "creating branches dir for GDPwUE"
svn mkdir file:///d:/data/repos/svn/tutorials/ue4/GDPwUE/branches -m "creating branches dir for GDPwUE"
Line 84: Line 91:
svn log -v
svn log -v
tree
tree

==== Import, last minute, lazy, safe ====
If you think you are done with the creation of directories, use
svn list file:///D:/data/repos/svn/tutorials/ue5/UE5-Character-Creation/trunk
to be sure the directory for import is there.
Now change to the directory you want to import from like
cd /d C:\work\tutorials\UE5-Character-Creation
Now you use the cursor keys to get the "svn list" line from before and just edit it to
svn import . file:///D:/data/repos/svn/tutorials/ue5/UE5-Character-Creation/trunk -m "initial import of project UE5-Character-Creation"
This way the chances for a wrong letter somewhere are lower. Yes, I am a coward in certain situations.


=== svn, What you normally need ===
=== svn, What you normally need ===
* get current version
* get current version
svn up
svn up
* add a file which is not yet managed by svn
* commit your changes
svn add <file>
* commit your changes (Windows uses here " instead of ')
svn commit -m '<description>'
svn commit -m '<description>'


Line 97: Line 116:


=== Create a branch from an existing Url: (use ", not ' with Windows) ===
=== Create a branch from an existing Url: (use ", not ' with Windows) ===
Below I use URLs with absolute paths. If you are inside a working directory, consider to use the "Relative URL" you can get with "svn info". Look at the chapter about tags to get an example. Branches and tags are created in the same way anyway.

svn copy https://192.168.20.1:3690/svn/src/c++/YourProject/trunk \
svn copy https://192.168.20.1:3690/svn/src/c++/YourProject/trunk \
https://192.168.20.1:3690/svn/src/c++/YourProject/branches/YourFixForBadError \
https://192.168.20.1:3690/svn/src/c++/YourProject/branches/YourFixForBadError \
Line 131: Line 152:
svn commit -m '<description>'
svn commit -m '<description>'


=== ignore files or directories (without /) ===
=== Create a tag ===
There are multiple ways to do it. You don't even need a working copy. The following is how I do it. And I do it of course in the best way possible (for me, because I don't know a lot, *ups*).
svn propedit svn:ignore .

* Go to your working directory which should normally be a checked out "trunk".
svn info
* Look at
** "Relative URL:" and
** "Revision:".

Relative URL should be something like
Relative URL: ^/examples/ShowActor/trunk

Now you do something like:
svn mkdir "^/examples/ShowActor/tags" -m "creating tags directory"
svn copy -r 9 "^/examples/ShowActor/trunk" "^/examples/ShowActor/tags/1.0-stairs-only" -m "creating tag"

Branches and Tags are "the same". They are cheap copies and you just have to use them the right way.
You will normally never checkout "/examples" or "/examples/ShowActor/". You will instead checkout "/examples/ShowActor/trunk" and perhaps use
svn switch "^/examples/ShowActor/tags/1.0-stairs-only"
to switch to that tag, build and try it. But do NOT commit to it. Pretty please! (Only commit to trunk and branches!)

Then switch back to your trunk with
svn switch "^/examples/ShowActor/trunk"


=== undo an "add" ===
=== undo an "add" ===
Line 161: Line 203:


=== svn, ignore ===
=== svn, ignore ===

==== Types ====
There are three ways to ignore files/directories:
There are three ways to ignore files/directories:


* in your repository you set ignores for this directory and all below and it just works, no need to think about it
# <li value="1"> in your repository you set ignores for this directory and all below and it just works, no need to think about it
svn propset svn:global-ignores "Intermediate" .
svn propset svn:global-ignores "Intermediate" .
* in your repository you set ignores for this directory and if you want it for all EXISTING sub-directories too you use "--recursive":
# <li value="2"> in your repository you set ignores for this directory and if you want it for all EXISTING sub-directories too you use "--recursive":
svn propset svn:ignore "Intermediate" .
svn propset svn:ignore "Intermediate" .
* in your configuration file for your svn installation in the "global-ignores" section you set it for all repositories at once, but have it only locally.
# <li value="3"> in your configuration file for your svn installation in the "global-ignores" section you set it for all repositories at once, but have it only locally.



==== What to use ====


So... in nearly all cases you want either "svn:global-ignores" or "svn:ignore".
So... in nearly all cases you want either "svn:global-ignores" or "svn:ignore".
Line 176: Line 220:
A new member of the team should not add "Intermediate" to the repository because he was not told yet not to do it.
A new member of the team should not add "Intermediate" to the repository because he was not told yet not to do it.
He will just not see it when working with svn normally.
He will just not see it when working with svn normally.

==== Use a file and a script to ease your life ====


How do you do it and keep sane?
How do you do it and keep sane?
Line 181: Line 227:
Create a file ".svnignore" with content like: (of course depending on YOUR needs, I added .sln here because this is for an Unreal Engine repository)
Create a file ".svnignore" with content like: (of course depending on YOUR needs, I added .sln here because this is for an Unreal Engine repository)
<pre>
<pre>
*.sln
.vs
.vsconfig
Binaries
Binaries
Build
DerivedDataCache
DesignTimeBuild
FileContentIndex
Intermediate
Intermediate
Releases
Saved
Saved
v17
DerivedDataCache
.vs
.vsconfig
*.sln
</pre>
</pre>


Create a script like "use-ignore-file.cmd" with content like:
Create a script like "use-ignore-file.cmd" with content like:
svn propset svn:global-ignores -F .svnignore .
svn propset svn:global-ignores -F .svnignore .
svn update


Add both files to svn. After using the script you will probably have to use "svn update" before you can do other stuff.
Add both files to svn. After using propset you will probably have to use "svn update" before you can do other stuff. That's why...


==== Notes about ignore ====


Keep in mind that these ignores only meddle with the normal display. Meaning a normal
Keep in mind that these ignores only meddle with the normal display. Meaning a normal

Latest revision as of 01:27, 5 August 2024

But if you'd like to use Tortoise (gui + command line):


see also

get svn

You need a working svn, so with Debian you would do something like

apt-get install subversion

while with Windows you either use winget

winget install TortoiseSVN

or get one of the Windows binaries:

  • SilkSVN for just the command line, as far as I know
  • TortoiseSVN to get a graphical interface in your explorer (or Total Commander), command line still available but has to be selected during install (I ALWAYS install the command line too, some things are just more understandable when done on the command line)
  • VisualSVN for an interface inside Visual Studio
  • Cirata which I have no idea about
  • some more clients

svn, creating a repository locally

  • either use the command line in Linux
svnadmin create /var/svn/repo01
  • or use the command line in Windows
svnadmin create d:\data\repos\svn\test
  • Test it under Linux
svn list /var/svn/repo01
  • Test it under Windows
svn list file:///D:/data/repos/svn/test/

As you see, svnadmin uses local paths and svn uses remote paths. You will not use svnadmin often or even not at all, so it is not that important to you.

If you are using TortoiseSVN you can skip the whole thing, just

  • use your Total Commander or File Explorer to show the folder where you want the new repository,
  • create an empty folder like "test2",
  • go inside the empty folder,
  • right click inside and select "TortoiseSVN / Create repository here".
  • done. :-)

using a local repository

  • Go to your working folder (you have one, right?), something like "C:\work".
  • with Linux
svn checkout /var/svn/repo01 testX01
  • with Windows
svn checkout file:///D:/data/repos/svn/test/ testX01
  • checkout with TortoiseSVN
    • right-click the empty area and
    • select "SVN Checkout..."
    • URL of repository: file:///D:/data/repos/svn/test/
    • Checkout directory: C:\work\test

Adding existing project to own trunk inside (new) local repository

  • go the folder where the new repository will be created
cd /D d:\data\repos\svn
  • create the new repository
svnadmin create tutorials
  • check it
svn list file:///d:/data/repos/svn/tutorials
  • think about the tree/dir structure we want
/
 ue4
    GDPwUE
          trunk
          branches
          tags
  • Create this structure in the repository: (consider to not use "--parents" so you find typing errors)
svn mkdir file:///d:/data/repos/svn/tutorials/ue4/GDPwUE/trunk -m "creating trunk dir for GDPwUE" --parents
svn mkdir file:///d:/data/repos/svn/tutorials/ue4/GDPwUE/branches -m "creating branches dir for GDPwUE"
svn mkdir file:///d:/data/repos/svn/tutorials/ue4/GDPwUE/tags -m "creating tags dir for GDPwUE"
  • import the project to trunk (the content of GDPwUE will be inside trunk)
svn import C:\work\tutorials\ue4\GDPwUE file:///d:/data/repos/svn/tutorials/ue4/GDPwUE/trunk -m "initial import of GDPwUE"
  • now move the original GDPwUE somewhere else for safekeeping, in case you did something wrong
  • checkout the project
cd /D c:/work/tutorials
svn checkout file:///d:/data/repos/svn/tutorials/ue4/GDPwUE/trunk GDPwUE
cd GDPwUE
svn log
svn log -q
svn log -v
tree

Import, last minute, lazy, safe

If you think you are done with the creation of directories, use

svn list file:///D:/data/repos/svn/tutorials/ue5/UE5-Character-Creation/trunk

to be sure the directory for import is there. Now change to the directory you want to import from like

cd /d C:\work\tutorials\UE5-Character-Creation

Now you use the cursor keys to get the "svn list" line from before and just edit it to

svn import . file:///D:/data/repos/svn/tutorials/ue5/UE5-Character-Creation/trunk -m "initial import of project UE5-Character-Creation"

This way the chances for a wrong letter somewhere are lower. Yes, I am a coward in certain situations.

svn, What you normally need

  • get current version
svn up
  • add a file which is not yet managed by svn
svn add <file>
  • commit your changes (Windows uses here " instead of ')
svn commit -m '<description>'


Get an idea about your svn-urls:

svn info

Create a branch from an existing Url: (use ", not ' with Windows)

Below I use URLs with absolute paths. If you are inside a working directory, consider to use the "Relative URL" you can get with "svn info". Look at the chapter about tags to get an example. Branches and tags are created in the same way anyway.

svn copy https://192.168.20.1:3690/svn/src/c++/YourProject/trunk \
https://192.168.20.1:3690/svn/src/c++/YourProject/branches/YourFixForBadError \
-m 'we have a bad bad error'

You just created the branch in the repository, now get it:

svn up

Do your changes and fixes, then

svn status

do get an idea which files you added or changed. If you added files, add them to subversion with

svn add <file>

Commit all your changes with (" for Windows)

svn commit -m '<description>' 

if it took a lot of time for all this, get the current trunk into your branch:

svn merge <url-to-trunk>
svn status
svn diff
svn commit


Go to your trunk

cd <whatever>src/c++/yourProject/trunk

if you are unsure, what you did:

svn diff <trunk-url> <branch-url>

merge the branch into the trunk:

svn merge <url-to-branch>
svn status
svn commit -m '<description>'

Create a tag

There are multiple ways to do it. You don't even need a working copy. The following is how I do it. And I do it of course in the best way possible (for me, because I don't know a lot, *ups*).

  • Go to your working directory which should normally be a checked out "trunk".
svn info
  • Look at
    • "Relative URL:" and
    • "Revision:".

Relative URL should be something like

Relative URL: ^/examples/ShowActor/trunk

Now you do something like:

svn mkdir "^/examples/ShowActor/tags" -m "creating tags directory"
svn copy -r 9 "^/examples/ShowActor/trunk" "^/examples/ShowActor/tags/1.0-stairs-only" -m "creating tag"

Branches and Tags are "the same". They are cheap copies and you just have to use them the right way. You will normally never checkout "/examples" or "/examples/ShowActor/". You will instead checkout "/examples/ShowActor/trunk" and perhaps use

svn switch "^/examples/ShowActor/tags/1.0-stairs-only" 

to switch to that tag, build and try it. But do NOT commit to it. Pretty please! (Only commit to trunk and branches!)

Then switch back to your trunk with

svn switch "^/examples/ShowActor/trunk"

undo an "add"

svn revert --recursive <folder>
svn revert --recursive .

other project as subdirectory, internal link

If you have a repository with the path

/c++/_internal

and you in some project like

/c++/myProject

you want to use the first one without using ../ you can use the following (the last . is important too, Windows: use " instead of ')

svn propset svn:externals '^/c++/_internal _internal' .
svn up

svn, commit a message with an apostrophe

What will not work:

svn commit -m 'user's test'

What should work

svn commit -m "user's test"

What we want to show here

 svn commit -m 'user'\''s test' 

So we have three parts in the commit

'user'
\'
's test'

svn, ignore

Types

There are three ways to ignore files/directories:

  1. in your repository you set ignores for this directory and all below and it just works, no need to think about it
svn propset svn:global-ignores "Intermediate" .
  1. in your repository you set ignores for this directory and if you want it for all EXISTING sub-directories too you use "--recursive":
svn propset svn:ignore "Intermediate" . 
  1. in your configuration file for your svn installation in the "global-ignores" section you set it for all repositories at once, but have it only locally.

What to use

So... in nearly all cases you want either "svn:global-ignores" or "svn:ignore".

Reason? You want it to work for everyone who checks out the repository or - how it is normal for large projects - parts of the repository. A new member of the team should not add "Intermediate" to the repository because he was not told yet not to do it. He will just not see it when working with svn normally.

Use a file and a script to ease your life

How do you do it and keep sane?

Create a file ".svnignore" with content like: (of course depending on YOUR needs, I added .sln here because this is for an Unreal Engine repository)

*.sln
.vs
.vsconfig
Binaries
Build
DerivedDataCache
DesignTimeBuild
FileContentIndex
Intermediate
Releases
Saved
v17

Create a script like "use-ignore-file.cmd" with content like:

svn propset svn:global-ignores -F .svnignore .
svn update

Add both files to svn. After using propset you will probably have to use "svn update" before you can do other stuff. That's why...

Notes about ignore

Keep in mind that these ignores only meddle with the normal display. Meaning a normal

svn status

will react to these ignores and show or not show something.

But nobody keeps you from adding a file/folder to svn, because the ignores ONLY change the display. After adding an ignored item to the repository, it will be handled like a normal item. The ignore will be ignored :-)


And if you want to see the status with the ignored files:

svn status --no-ignore