MoinMoin Logo
  • Comments
  • Immutable Page
  • Menu
    • Navigation
    • RecentChanges
    • FindPage
    • Local Site Map
    • Help
    • HelpContents
    • HelpOnMoinWikiSyntax
    • Display
    • Attachments
    • Info
    • Raw Text
    • Print View
    • Edit
    • Load
    • Save
  • Login

Navigation

  • Start
  • Sitemap
Revision 44 as of 2019-01-05 20:33:17
  • Subversion

Subversion

Subversion is an open source version control system

https://subversion.apache.org/

Update

svn update

Commit

svn commit -m 'message'
svn protected/* themes/* commit -m 'message'

Add unversioned files

/usr/bin/svnaddunversioned.sh:

   1 #!/bin/sh
   2 svn status | grep ? | awk '//{print $2}' | xargs -i svn add {}
   3 
   4 # revert add 
   5 svn revert addedFile
  • chmod 755 /usr/bin/svnaddunversioned.sh

Branches

http://svnbook.red-bean.com/en/1.7/svn.branchmerge.using.html

svn copy http://svn.example.com/repos/calc/trunk http://svn.example.com/repos/calc/branches/my-calc-branch -m "Creating a private branch of /calc/trunk."
svn checkout http://svn.example.com/repos/calc/branches/my-calc-branch my-calc-branch 

Ignore one folder

http://stackoverflow.com/questions/11293539/equivalent-of-gitignore-file-with-subversion

C# example:

  • cd ~/trunkx
  • svn propset svn:ignore "bin" .

Ignore several files folders

http://sdesmedt.wordpress.com/2006/12/10/how-to-make-subversion-ignore-files-and-folders/

svnignore.txt

obj
bin

Issue the command to ignore the folders listed inside the file

  • svn propset svn:ignore -F svnignore.txt .
  • svn status --no-ignore # see ignored files
  • svn propedit svn:ignore . # shows ignore list on editor
  • SVN_EDITOR=nano
  • svn propedit svn:ignore . # uses nano
  • svn proplist -v -R # shows all properties recursively

Add to ~/.bashrc

# export SVN_EDITOR=vi
export SVN_EDITOR=nano

Merge

  • cd mergeDestination
  • svn merge --accept postpone originFolder -r1234:HEAD #postpone to resolve conflicts later
  • svn status | grep '^C ' # only show files with conflits
  • svn resolve --accept working filex #accepts that working copy of filex does not have conflicts
  • svn update --accept postpone # updates working copy and automatically postpones conflict resolution

Diff between branches

  • svn diff --summarize http://example/svn/repository/branch1 http://example/svn/repository/branch2

Commit with message(s) in file

  • nano messages.txt
  • svn commit -F messages.txt --username userx

Files added or modified

  •  svn status | grep "^A\|^M" 

Cherrypicking

  • svn diff -c 1234 ~/calc/trunk # see diff for revision 1234
  • svn merge -c 1234 ~/calc/trunk # merge revision 1234

Solve conflict

  • svn resolved path/file # mark as solved

Revert working copy

  • svn revert --recursive .

Mark script as executable

  • svn propset svn:executable on xyz.sh

Search logs by username

  • svn log --search username

Get folder without content

  • svn ls
  • svn up "folderx" -N

svnserve

The svnserve program is a lightweight server, capable of speaking to clients over TCP/IP using a custom, stateful protocol. Listens port 3690 http://svnbook.red-bean.com/en/1.7/svn.serverconfig.svnserve.html

  • mkdir -p /tmp/svnserver
  • svnserve -d -r /tmp/svnserver
  • svnadmin create --fs-type fsfs /tmp/svnserver/testrepo
  • cd /tmp
  • svn checkout svn://localhost/testrepo
  • cd testrepo

/tmp/svnserver/test/conf/passwd

[users]
harry = 1234
sally = 1234

/tmp/svnserver/test/conf/svnserve.conf

[general]
password-db = passwd
[sasl]
use-sasl = false

   1 touch a
   2 svn add a
   3 svn commit a --username harry --password 1234
   4 svn log
   5 svn up .
   6 svn log
   7 svn ls
   8 mkdir branch tag trunk
   9 svn rm a
  10 svn status
  11 svn add branch/ tag/ trunk/
  12 svn status
  13 svn commit -m "Created branch tag trunk" --username harry --password 1234

   1 #!/bin/sh
   2 mkdir -p /tmp/svnserver/testrepo
   3 svnserve -d -r /tmp/svnserver
   4 svnadmin create --fs-type fsfs /tmp/svnserver/testrepo
   5 cd /tmp/svnserver/testrepo
   6 echo -e "[users]\nharry = 1234\nsally = 1234\n" > conf/passwd
   7 echo -e "[general]\npassword-db = passwd\n[sasl]\nuse-sasl = false\n" > conf/svnserve.conf
   8 BASE_SVN_REPO=svn://localhost/testrepo
   9 CREDENTIALS="--username harry --password 1234"
  10 cd /tmp
  11 svn checkout $BASE_SVN_REPO
  12 cd testrepo 
  13 mkdir branches tag trunk
  14 svn add branches/ tag/ trunk/
  15 svn status
  16 svn commit -m "Created branches tag trunk" $CREDENTIALS
  17 # Committed revision 1.
  18 svn up .
  19 BASE=/tmp/testrepo
  20 cd $BASE/trunk
  21 echo -e "trunk 1" > dummy.txt
  22 svn add dummy.txt
  23 svn commit -m "Created dummy1.txt in trunk" $CREDENTIALS
  24 #Committed revision 2
  25 svn up .
  26 svn copy $BASE_SVN_REPO/trunk $BASE_SVN_REPO/branches/feature_branch1 $CREDENTIALS  -m "created feature branch1"
  27 # Committed revision 3.
  28 cd $BASE
  29 svn up .
  30 cd $BASE/branches/feature_branch1
  31 echo -e "fb1 1" >> dummy.txt
  32 svn commit -m "Changed dummy1.txt in feature_branch1" $CREDENTIALS
  33 #Committed revision 4
  34 svn up .
  35 cd $BASE/trunk
  36 echo -e "\ntrunk 2\n" >> dummy.txt 
  37 svn commit -m "Changed trunk" $CREDENTIALS
  38 svn up .
  39 # Committed revision 5
  40 # Synch from trunk to feature_branch1
  41 cd $BASE/branches/feature_branch1/
  42 svn up .
  43 svn merge $BASE_SVN_REPO/trunk $CREDENTIALS --accept postpone 
  44 # Conflict discovered in file 'dummy.txt'. postpone
  45 vi dummy.txt
  46 svn resolve --accept working dummy.txt
  47 svn status
  48 svn commit -m "synch merge from trunk to feature_branch1" $CREDENTIALS
  49 svn up .
  50 # Committed revision 6.
  51 # create feature branch2 from feature branch1
  52 svn copy $BASE_SVN_REPO/branches/feature_branch1 $BASE_SVN_REPO/branches/feature_branch2 $CREDENTIALS -m "created feature branch2 from feature branch1"
  53 # Committed revision 7.
  54 svn up .
  55 cd $BASE
  56 svn up .
  57 cd $BASE/branches/feature_branch2/
  58 echo -e "\nfb2 1\n" >> dummy.txt
  59 svn commit -m "changed feature branch2" $CREDENTIALS
  60 svn up . 
  61 # Committed revision 8.
  62 cd $BASE/branches/feature_branch1
  63 echo -e "\nfb1 2\n" >> dummy.txt 
  64 svn commit -m "changed feature branch1" $CREDENTIALS
  65 svn up .
  66 # Committed revision 9
  67 # synch feat_branch2 from feat_branch1
  68 cd $BASE/branches/feature_branch2/
  69 svn up .
  70 svn merge $BASE_SVN_REPO/branches/feature_branch1 $CREDENTIALS --accept postpone 
  71 # Conflict discovered in file 'dummy.txt'. postpone
  72 vi dummy.txt
  73 svn resolve --accept working dummy.txt
  74 svn status
  75 svn commit -m "synch merge from feature_branch1 to feature_branch2" $CREDENTIALS
  76 svn up .
  77 # Committed revision 10.
  78 cd $BASE/trunk
  79 echo -e "\ntrunk 3\n" >> dummy.txt 
  80 svn commit -m "Changed trunk" $CREDENTIALS
  81 svn up .
  82 # Committed revision 11.
  83 # synch fb1 with trunk
  84 cd $BASE/branches/feature_branch1
  85 svn merge $BASE_SVN_REPO/trunk $CREDENTIALS --accept postpone 
  86 vi dummy.txt # solve conflicts
  87 svn resolve --accept working dummy.txt
  88 svn commit -m "synch merge from parent trunk to feature branch1" $CREDENTIALS
  89 # Committed revision 12.
  90 svn up .
  91 cd $BASE/trunk/
  92 svn up .
  93 svn merge $BASE_SVN_REPO/branches/feature_branch1 $CREDENTIALS --accept postpone 
  94 svn status
  95 svn commit -m "got changes into trunk from feature branch1 (reintegrate)" $CREDENTIALS
  96 # Committed revision 13.
  97 # terminate feature branch 1
  98 svn rm $BASE_SVN_REPO/branches/feature_branch1 $CREDENTIALS -m "removed feature branch1"
  99 # Committed revision 14.
 100 cd $BASE
 101 svn up .
 102 # add new entry to trunk
 103 cd $BASE/trunk
 104 echo -e "\ntrunk 4\n" >> dummy.txt 
 105 svn commit -m "changed trunk" $CREDENTIALS
 106 #Committed revision 15
 107 svn up . 
 108 
 109 svn diff $BASE_SVN_REPO/trunk@13 $BASE_SVN_REPO/trunk@15  $CREDENTIALS 
 110 # added trunk 4
 111 svn diff $BASE_SVN_REPO/trunk@3 $BASE_SVN_REPO/trunk@13  $CREDENTIALS 
 112 # added fb1 1 , trunk 2 , fb1 2 , trunk 3
 113 # the synch from trunk to feature branch 2 should have ....
 114 # trunk1, trunk2, trunk3, trunk4, fb2 1, fb1 1, fb1 2, 7 elements
 115 # merge from integrate revision to head of trunk
 116 cd $BASE/branches/feat_branch2
 117 svn merge $BASE_SVN_REPO/trunk@13 $BASE_SVN_REPO/trunk@HEAD $CREDENTIALS --accept postpone 
 118 # has all the elements
 119 
 120 svn merge $BASE_SVN_REPO/trunk@15 $BASE_SVN_REPO/trunk@15 $CREDENTIALS --accept postpone
 121 # only has 5 elements
 122 
 123 # from fb1 creation to reintegration 13
 124 svn merge $BASE_SVN_REPO/trunk@3 $BASE_SVN_REPO/trunk@13 $CREDENTIALS --accept postpone 
 125 # has six elements, trunk 4 was added in r15
 126 

Show svn diff side by side

   1 svn --diff-cmd "diff" --extensions "-y" diff
   2 svn --diff-cmd "diff" --extensions "-y -W250" diff | colordiff | less -rS
   3 svn --diff-cmd "diff" --extensions "-y -W250 --suppress-common-lines" diff | colordiff | less -rS

Revert commited file to previous revision

#1234 previous revision
svn merge -c -1234 test.py
svn commit
svn up .

Merge with revision range

   1 cd ~/tmp
   2 svn co https://feature_branch
   3 cd feature_branch
   4 svn merge https://parent_branch -r start:end . --accept=postpone
   5 # the range of revisions is ]start,end] so only start+1 is applied until end.
   6 # sync merge
   7 

svn help merge | less

Merge types:

  • 'sync' merge, merge from the parent branch to the feature branch is called a 'sync'
  • 'reintegrate' merge, merge from the feature branch to the parent branch is called a 'reintegrate'
  • 'cherry-pick' merge, used to merge specific revisions (or revision ranges) from one branch to another.
  • '2-URL merge', use this merge variant only if the other variants do not apply to your situation, as this variant can be quite complex to master.

The 'Feature Branch' Merging Pattern

A developer creates a branch and commits a series of changes that implement a new feature. The developer periodically merges all the latest changes from the parent branch so as to keep the development branch up to date with those changes. When the feature is complete, the developer performs a merge from the feature branch to the parent branch to re-integrate the changes.

         parent --+----------o------o-o-------------o--
                   \            \           \      /
                    \          merge      merge  merge
                     \            \           \  /
         feature      +--o-o-------o----o-o----o-------

A merge from the parent branch to the feature branch is called a 'sync' or 'catch-up' merge, and a merge from the feature branch to the parent branch is called a 'reintegrate' merge.

Sync Merge Example

                                 ............
                                .            .
         trunk  --+------------L--------------R------
                   \                           \
                    \                          |
                     \                         v
         feature      +------------------------o-----
                             r100            r200

Reintegrate Merge Example

                    rW                   rX
         trunk ------+--------------------L------------------o
                      \                    .                 ^
                       \                    .............   /
                        \                                . /
         feature         +--------------------------------R

Cherry-pick Merge Example

            1.x-release  +-----------------------o-----
                        /                        ^
                       /                         |
                      /                          |
         trunk ------+--------------------------LR-----
                                                r50

2-URL merge example

Two source URLs are specified, identifying two trees on the same branch or on different branches. The trees are compared and the difference from SOURCE1@REV1 to SOURCE2@REV2 is applied to the working copy of the target branch at TARGET_WCPATH.

Two features have been developed on separate branches called 'foo' and 'bar'. It has since become clear that 'bar' should be combined with the 'foo' branch for further development before reintegration. Although both feature branches originate from trunk, they are not directly related -- one is not a direct copy of the other. A 2-URL merge is necessary.

The 'bar' branch has been synced with trunk up to revision 500. (If this revision number is not known, it can be located using the 'svn log' and/or 'svn mergeinfo' commands.) The difference between trunk@500 and bar@HEAD contains the complete set of changes related to feature 'bar', and no other changes. These changes are applied to the 'foo' branch.

                           foo  +-----------------------------------o
                               /                                    ^
                              /                                    /
                             /              r500                  /
         trunk ------+------+-----------------L--------->        /
                      \                        .                /
                       \                        ............   /
                        \                                   . /
                    bar  +-----------------------------------R

In the diagram above, L marks the left side (trunk@500) and R marks the right side (bar@HEAD) of the merge. The difference between the left and right side is applied to the target working copy path, in this case a working copy of the 'foo' branch.

The exact changes applied by a 2-URL merge can be previewed with svn's diff command, which is a good idea to verify if you do not have the luxury of a clean working copy to merge to.

  • MoinMoin Powered
  • Python Powered
  • GPL licensed
  • Valid HTML 4.01