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:
- 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 #!/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
- apt install colordiff
Revert commited file to previous revision
#1234 previous revision svn merge -c -1234 test.py svn commit svn up .
1 # All you need to do is to specify a reverse difference. (You can do this by specifying --revision 392:391, or by an equivalent --change -392.)
2 #svn merge ^/calc/trunk . -c-392
3 svn merge ^/calc/trunk . --revision 392:391
4 svn st
5 svn diff
6 svn commit -m "Undoing erroneous change committed in r392."
7 ####
8 cd branch
9 svn revert . -R # undo local changes
10 svn up .
11 svn log | less # see version
12 svn merge . --revision HEAD:<prev_revision>
13 svn commit -m "Reverted to revision xyz"
Merge with revision range
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.
testrepo2 , sync merge and 2 URL merge
1 #!/bin/sh
2 # as root
3 rm -rf /tmp/svnserver/testrepo2
4 mkdir -p /tmp/svnserver/testrepo2
5 svnserve -d -r /tmp/svnserver
6 svnadmin create --fs-type fsfs /tmp/svnserver/testrepo2
7 cd /tmp/svnserver/testrepo2
8 echo -e "[users]\nharry = 1234\nsally = 1234\n" > conf/passwd
9 echo -e "[general]\npassword-db = passwd\n[sasl]\nuse-sasl = false\n" > conf/svnserve.conf
10 exit
11 # as normal user
12 BASE_SVN_REPO=svn://localhost/testrepo2
13 CREDENTIALS="--username harry --password 1234"
14 cd /tmp
15 rm -rf testrepo2
16 svn checkout $BASE_SVN_REPO
17 cd testrepo2
18 mkdir branches tags trunk
19 svn add branches/ tags/ trunk/
20 svn status
21 svn commit -m "Created branches tags trunk" $CREDENTIALS
22 # Committed revision 1.
23 # if error appears with txn-current-lock': Permission denied, run the svnserve as root ...
24 svn up .
25
26 BASE=/tmp/testrepo2
27 cd $BASE/trunk
28 echo -e "t1" > dummy.txt
29 svn add dummy.txt
30 svn commit -m "Created dummy1.txt in trunk" $CREDENTIALS
31 #Committed revision 2
32 svn up .
33
34 echo -e "t2\n" >> dummy.txt
35 svn commit -m "Added t2 to dummy1.txt in trunk" $CREDENTIALS
36 # Committed revision 3.
37 svn up .
38
39 #create feature branch fb1
40 svn copy $BASE_SVN_REPO/trunk $BASE_SVN_REPO/branches/fb1 $CREDENTIALS -m "Created fb1"
41 # Committed revision 4.
42
43 cd $BASE/trunk
44 echo -e "t3\n" >> dummy.txt
45 svn commit -m "Added t3 to dummy1.txt in trunk" $CREDENTIALS
46 # Committed revision 5.
47 svn up .
48
49 cd $BASE
50 svn up .
51 cd $BASE/branches/fb1
52 echo -e "fb1_1" >> dummy.txt
53 svn commit -m "Added fb1_1 to dummy1.txt in fb1" $CREDENTIALS
54 #Committed revision 6
55 svn up .
56
57 cd $BASE/trunk
58 echo -e "t4\n" >> dummy.txt
59 svn commit -m "Added t4 to dummy.txt in trunk" $CREDENTIALS
60 # Committed revision 7
61 svn up .
62
63 # create feature branch fb2
64 svn copy $BASE_SVN_REPO/trunk $BASE_SVN_REPO/branches/fb2 $CREDENTIALS -m "Created branch fb2"
65 # Committed revision 8
66 svn up .
67
68 cd $BASE/branches/fb1
69 echo -e "fb1_2\n" >> dummy.txt
70 svn commit -m "Added fb1_2 to dummy.txt in fb1" $CREDENTIALS
71 # Committed revision 9
72 svn up .
73
74 cd $BASE/trunk
75 echo -e "t5\n" >> dummy.txt
76 svn commit -m "Added t5 to dummy.txt in trunk" $CREDENTIALS
77 # Committed revision 10
78 svn up .
79
80 cd $BASE
81 svn up .
82
83 cd $BASE/branches/fb2
84 echo -e "fb2_1\n" >> dummy.txt
85 svn commit -m "Added fb2_1 to dummy.txt in fb2" $CREDENTIALS
86 # Committed revision 11
87 svn up .
88
89 cd $BASE/trunk
90 echo -e "t6\n" >> dummy.txt
91 svn commit -m "Added t6 to dummy.txt in trunk" $CREDENTIALS
92 # Committed revision 12
93 svn up .
94
95 cd $BASE/branches/fb2
96 echo -e "fb2_2\n" >> dummy.txt
97 svn commit -m "Added fb2_2 to dummy.txt in fb2" $CREDENTIALS
98 # Committed revision 13
99 svn up .
100
101 cd $BASE/trunk
102 echo -e "t7\n" >> dummy.txt
103 svn commit -m "Added t7 to dummy.txt in trunk" $CREDENTIALS
104 # Committed revision 14
105 svn up .
106
107 # Sync merge from trunk to fb1
108 cd $BASE/branches/fb1/
109 svn up .
110 # will get t3 to t6 revisions ]3:12] -> 5,7,10,12
111 svn merge $BASE_SVN_REPO/trunk -r3:12 $CREDENTIALS --accept postpone
112 # Conflict discovered in file 'dummy.txt'. postpone
113 vi dummy.txt
114 svn resolve --accept working dummy.txt
115 svn status
116 svn commit -m "sync merge from trunk to fb1" $CREDENTIALS
117 # Committed revision 15.
118 svn up .
119
120 # Sync merge from trunk to fb2
121 cd $BASE/branches/fb2/
122 svn up .
123 # will get t5 to t7 revisions ]7:14] -> revisions 10,12,14
124 svn merge $BASE_SVN_REPO/trunk -r7:14 $CREDENTIALS --accept postpone
125 # Conflict discovered in file 'dummy.txt'. postpone
126 vi dummy.txt
127 svn resolve --accept working dummy.txt
128 svn status
129 svn commit -m "sync merge from trunk to fb2" $CREDENTIALS
130 # Committed revision 16.
131 svn up .
132
133 # test 2-URL merge, put changes made into feature branch fb1 into feature branch fb2
134 # the feature branches must be synchronized with the parent branch before doing this
135 cd $BASE
136 svn up .
137 cd $BASE/branches/fb2/
138 svn up .
139 svn diff $BASE_SVN_REPO/trunk@12 $BASE_SVN_REPO/branches/fb1@HEAD
140 # shows added fb1_1 and fb1_2 in branch fb1 when compared to trunk in the revisin used to sync
141 svn merge $BASE_SVN_REPO/trunk@12 $BASE_SVN_REPO/branches/fb1@HEAD --accept postpone
142 svn commit -m "2-URL merge with diff between trunk and fb1 to fb2" $CREDENTIALS
143 # Committed revision 17.
144 svn up .
145
146 svn diff $BASE_SVN_REPO/trunk $BASE_SVN_REPO/branches/fb1@HEAD
147 # fb1 has entries for fb1 and is missing t7
148 svn diff $BASE_SVN_REPO/trunk $BASE_SVN_REPO/branches/fb2@HEAD
149 # fb2 branch has added entries for fb1 and fb2 when compared to trunk
150
151 # integrate feature branch fb2 in trunk
152 cd $BASE/trunk/
153 svn up .
154 svn merge $BASE_SVN_REPO/branches/fb2 $CREDENTIALS --accept postpone
155 cat dummy.txt
156 svn status
157 svn commit -m "Got changes into trunk from feature branch fb2 (reintegrate)" $CREDENTIALS
158 # Committed revision 18.
159 svn up .
Before the 2-Url merge feature branches must be synchronized with their parent branch. Mergeinfo might not allow the application of revisions 10 and 12 to fb2 if done after the 2-URL merge.
External item (link)
cd /home/user/container_folder echo -e "folder https://example.org/folder\n" > ~/svn_externals.txt svn propset svn:externals -F ~/svn_externals.txt . svn up . svn proplist svn propget svn:externals
Update to revision
svn up -r <revisionId>
Go to previous revision
1 svn merge -r HEAD:<revision> .