Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
| versioncontrol:svn_merging [2006/09/24 12:46] – NikClayton | versioncontrol:svn_merging [2022/10/07 03:00] (current) – Move bakeoff stuff under a single namespace KubilayKocak | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | **NOTE**: This is from the VCS bakeoff. | ||
| + | |||
| + | Please see http:// | ||
| + | |||
| ====== Merging with Subversion ====== | ====== Merging with Subversion ====== | ||
| - | **Note:** Nik's actively updating this page. | + | **NOTE**: Subversion 1.5 has //merge tracking// built-in. You no longer need svnmerge. See http:// |
| ===== Background ===== | ===== Background ===== | ||
| Line 25: | Line 29: | ||
| ==== Repository creation ==== | ==== Repository creation ==== | ||
| - | First, we need to create a repository and populate it with some files. | + | First, we need to create a repository and populate it with some files. |
| < | < | ||
| Line 215: | Line 219: | ||
| * `svnmerge unblock` makes revisions blocked with `svnmerge block` available for merge again. | * `svnmerge unblock` makes revisions blocked with `svnmerge block` available for merge again. | ||
| * `svnmerge avail` supports `--diff` and `--log` options (amongst others) that will show the available changes as a diff, or as a list of log messages, instead of the default list of revisions. | * `svnmerge avail` supports `--diff` and `--log` options (amongst others) that will show the available changes as a diff, or as a list of log messages, instead of the default list of revisions. | ||
| + | * When you run `svnmerge merge` it collects the log messages of the revisions, and stores them in a file in the current directory. | ||
| == Project branch merge walkthrough == | == Project branch merge walkthrough == | ||
| Line 248: | Line 253: | ||
| Transmitting file data . | Transmitting file data . | ||
| Committed revision 13.}}} | Committed revision 13.}}} | ||
| + | |||
| + | So this change to -current was ''' | ||
| + | |||
| + | Switch to the directory that contains the trustedbsd project, make sure it's up to date, and initialise the merge tracking property. | ||
| {{{ | {{{ | ||
| % cd ../ | % cd ../ | ||
| % svn update | % svn update | ||
| - | At revision 13}}} | + | At revision 13 |
| + | % svnmerge init | ||
| + | property ' | ||
| + | |||
| + | % svn commit -m '" | ||
| + | Sending | ||
| + | |||
| + | Committed revision 14.}}} | ||
| + | |||
| + | We can make some local changes to the trustedbsd project, and commit them. | ||
| + | |||
| + | {{{ | ||
| + | % echo ' | ||
| + | % svn commit -m ' | ||
| + | Sending | ||
| + | Transmitting file data . | ||
| + | Committed revision 15.}}} | ||
| + | |||
| + | And we can find out which revisions in `src/trunk` are available for merging. | ||
| + | |||
| + | {{{ | ||
| + | % svnmerge avail | ||
| + | 13}}} | ||
| + | |||
| + | Merging those changes is easy (so far, this is just like doing an MFC to a -stable branch, as described previously). | ||
| + | |||
| + | {{{ | ||
| + | % svnmerge merge -r 13 | ||
| + | U foo | ||
| + | |||
| + | property ' | ||
| + | |||
| + | % svn update | ||
| + | At revision 15. | ||
| + | % svn commit -m ' | ||
| + | Sending | ||
| + | Sending | ||
| + | Transmitting file data . | ||
| + | Committed revision 16.}}} | ||
| + | |||
| + | === Merge from project branch back to -current === | ||
| + | |||
| + | This is more interesting. | ||
| + | |||
| + | First, we need to initialise merge tracking. | ||
| + | |||
| + | This is slightly longer winded, purely because we need to know when the branch was created. | ||
| + | |||
| + | Fortunately, | ||
| + | |||
| + | To find out when the branch was created run `svn log` on the branch. | ||
| + | |||
| + | {{{% cd ../../../ | ||
| + | % svn update | ||
| + | At revision 16. | ||
| + | % cd freebsd/ | ||
| + | % svn log --stop-on-copy ../ | ||
| + | ------------------------------------------------------------------------ | ||
| + | r16 | nik | 2006-09-22 22:12:24 +0100 (Fri, 22 Sep 2006) | 1 line | ||
| + | |||
| + | MFC | ||
| + | ------------------------------------------------------------------------ | ||
| + | r15 | nik | 2006-09-22 22:11:21 +0100 (Fri, 22 Sep 2006) | 1 line | ||
| + | |||
| + | Special security changes | ||
| + | ------------------------------------------------------------------------ | ||
| + | r14 | nik | 2006-09-22 22:10:44 +0100 (Fri, 22 Sep 2006) | 1 line | ||
| + | |||
| + | " | ||
| + | ------------------------------------------------------------------------ | ||
| + | r12 | nik | 2006-09-22 22:09:20 +0100 (Fri, 22 Sep 2006) | 1 line | ||
| + | |||
| + | Start the trustedbsd project | ||
| + | ------------------------------------------------------------------------}}} | ||
| + | |||
| + | we see that the trustedbsd project was branched from the trunk at r12. | ||
| + | |||
| + | Now we can run `svnmerge init`. | ||
| + | |||
| + | We also need to specify where we're merging changes from. This is going to the `trustedbsd/ | ||
| + | |||
| + | {{{ | ||
| + | % svnmerge init -r 1-12 ../ | ||
| + | property ' | ||
| + | |||
| + | % svn commit -m '" | ||
| + | Sending | ||
| + | |||
| + | Committed revision 17.}}} | ||
| + | |||
| + | Now the merge tracking information is initialised we can find out whether there are any revisions to merge. | ||
| + | |||
| + | {{{ | ||
| + | % svnmerge avail | ||
| + | 14-16}}} | ||
| + | |||
| + | This doesn' | ||
| + | |||
| + | {{{ | ||
| + | % svnmerge avail -b | ||
| + | 15}}} | ||
| + | |||
| + | As you can see, that's generated the correct output. | ||
| + | |||
| + | {{{ | ||
| + | % svn merge merge -r 15 | ||
| + | U bar | ||
| + | |||
| + | property ' | ||
| + | |||
| + | % svn commit -m 'Merge r15 from trustedbsd project' | ||
| + | Sending | ||
| + | Sending | ||
| + | Transmitting file data . | ||
| + | Committed revision 18.}}} | ||
| + | |||
| + | === Merging from multiple project branches === | ||
| + | |||
| + | That's demonstrated how to merge from -current to a project branch, and also from a project branch back to -current. | ||
| + | |||
| + | Start by creating a second project branch, and using `svnmerge init` to initialise merge tracking for that branch. | ||
| + | |||
| + | {{{ | ||
| + | % cd ../../../ | ||
| + | % svn update | ||
| + | At revision 18. | ||
| + | % svn copy freebsd/ | ||
| + | A | ||
| + | % svn commit -m ' | ||
| + | Adding | ||
| + | |||
| + | Committed revision 19. | ||
| + | % cd projects/ | ||
| + | % svnmerge init | ||
| + | property ' | ||
| + | |||
| + | % svn commit -m " | ||
| + | Sending | ||
| + | |||
| + | Committed revision 20.}}} | ||
| + | |||
| + | Now go and make changes in three places -- in the geom project, in the trustedbsd project, and in -current. | ||
| + | |||
| + | {{{ | ||
| + | % echo 'A geom change' | ||
| + | % svn commit -m ' | ||
| + | Sending | ||
| + | Transmitting file data . | ||
| + | Committed revision 21. | ||
| + | % cd ../ | ||
| + | % svn update | ||
| + | At revision 21. | ||
| + | % echo 'A trustedbsd change' | ||
| + | % svn commit -m ' | ||
| + | Sending | ||
| + | Transmitting file data . | ||
| + | Committed revision 22. | ||
| + | % cd ../../.. | ||
| + | % svn update | ||
| + | At revision 22. | ||
| + | % cd freebsd/ | ||
| + | % echo ' | ||
| + | % svn commit -m ' | ||
| + | Sending | ||
| + | Transmitting file data . | ||
| + | Committed revision 23.}}} | ||
| + | |||
| + | With changes in both projects, lets find out which revisions are available to merge. | ||
| + | |||
| + | {{{ | ||
| + | % svnmerge avail -b | ||
| + | 22}}} | ||
| + | |||
| + | That doesn' | ||
| + | |||
| + | As you've probably realised, this is because the merge tracking record that says that `projects/ | ||
| + | |||
| + | Again, we need to use `svn log --stop-on-copy` to find out when the geom project was created. | ||
| + | |||
| + | {{{ | ||
| + | % svn log --stop-on-copy ../ | ||
| + | ------------------------------------------------------------------------ | ||
| + | r21 | nik | 2006-09-22 22:16:36 +0100 (Fri, 22 Sep 2006) | 1 line | ||
| + | |||
| + | Change baz to support geom | ||
| + | ------------------------------------------------------------------------ | ||
| + | r20 | nik | 2006-09-22 22:16:16 +0100 (Fri, 22 Sep 2006) | 1 line | ||
| + | |||
| + | " | ||
| + | ------------------------------------------------------------------------ | ||
| + | r19 | nik | 2006-09-22 22:15:45 +0100 (Fri, 22 Sep 2006) | 1 line | ||
| + | |||
| + | Create GEOM project | ||
| + | ------------------------------------------------------------------------ | ||
| + | % svnmerge init -r 1-19 ../ | ||
| + | property ' | ||
| + | |||
| + | % svn update | ||
| + | At revision 23. | ||
| + | % svn commit -m '" | ||
| + | Sending | ||
| + | |||
| + | Committed revision 24.}}} | ||
| + | |||
| + | With that done, `svnmerge avail -b` should print something useful. | ||
| + | |||
| + | {{{ | ||
| + | % svnmerge avail -b | ||
| + | svnmerge: multiple heads found. Explicit head argument (-S/--head) required. | ||
| + | The head values available are: | ||
| + | file:/// | ||
| + | file:/// | ||
| + | |||
| + | As this error explains, now that we've told `svnmerge` that two branches can be merged on the trunk we need to be more explicit with some commands, and specify which merge source we're talking about. | ||
| + | |||
| + | {{{ | ||
| + | % svnmerge avail -S ../ | ||
| + | 22 | ||
| + | % svnmerge avail -S ../ | ||
| + | 21}}} | ||
| + | |||
| + | This restriction applies to merging revisions as well. We can merge the changes in from the branch, either in one lump, or (as in this case) one by one, but we need to specify the merge source path as well as the revision to `svnmerge merge`. | ||
| + | |||
| + | {{{ | ||
| + | % svnmerge merge -r 21 | ||
| + | svnmerge: multiple heads found. Explicit head argument (-S/--head) required. | ||
| + | The head values available are: | ||
| + | file:/// | ||
| + | file:/// | ||
| + | % svnmerge merge -r 21 -S ../ | ||
| + | U baz | ||
| + | |||
| + | property ' | ||
| + | |||
| + | % svn commit -m 'Merge r21 from geom' | ||
| + | Sending | ||
| + | Sending | ||
| + | Transmitting file data . | ||
| + | Committed revision 25. | ||
| + | % svn update | ||
| + | At revision 25. | ||
| + | % svnmerge merge -r 22 -S ../ | ||
| + | U bar | ||
| + | |||
| + | property ' | ||
| + | |||
| + | % svn commit -m 'Merge r22 from trustedbsd' | ||
| + | Sending | ||
| + | Sending | ||
| + | Transmitting file data . | ||
| + | |||
| + | Committed revision 26.}}} | ||
| + | |||
| + | So that's r25 (which came from geom) and r26 (which came from trustedbsd) committed. | ||
| + | |||
| + | First, trustedbsd. | ||
| + | |||
| + | {{{ | ||
| + | % cd ../ | ||
| + | % svnmerge avail -b | ||
| + | 23-25}}} | ||
| + | |||
| + | That's correct, and we could merge those back in to this branch if we so choose. | ||
| + | |||
| + | {{{ | ||
| + | % cd ../ | ||
| + | % svnmerge avail -b | ||
| + | svnmerge: multiple heads found. Explicit head argument (-S/--head) required. | ||
| + | The head values available are: | ||
| + | file:/// | ||
| + | file:/// | ||
| + | |||
| + | That looks odd. The geom branch isn't merging directly with the trustedbsd branch, so why is it showing up in this list? | ||
| + | |||
| + | Recall that the geom branch was copied from trunk ''' | ||
| + | |||
| + | Now there' | ||
| + | |||
| + | Recall that this information is recorded in properties. | ||
| + | |||
| + | First, we can find out the properties that are set here. | ||
| + | |||
| + | {{{ | ||
| + | % svn proplist | ||
| + | Properties on ' | ||
| + | svnmerge-integrated}}} | ||
| + | |||
| + | Now we can find out the value of the `svnmerge-integrated` property. | ||
| + | |||
| + | {{{ | ||
| + | % svn propget svnmerge-integrated | ||
| + | / | ||
| + | |||
| + | That shows that r1-18 from `src/trunk` are integrated, as are r1-12 and r15 from trustedbsd. | ||
| + | |||
| + | {{{ | ||
| + | % svn propset svnmerge-integrated / | ||
| + | property ' | ||
| + | % svn commit -m ' | ||
| + | Sending | ||
| + | |||
| + | Committed revision 27}}} | ||
| + | |||
| + | And now `svnmerge avail` prints the correct list of revisions, without prompting for the `-S` parameter. | ||
| + | |||
| + | {{{ | ||
| + | % svnmerge avail -b | ||
| + | 23,26}}} | ||
| + | |||
| + | Those revisions can be merged using `svnmerge merge`. | ||
| + | |||
| + | == Conclusion == | ||
| + | |||
| + | This has hopefully shown how Subversion, plus svnmerge, can be used to support all the project' | ||
| + | |||
| + | * Merge from -current to -stable. | ||
| + | * Merge from -stable to an errata branch (which is just a special case of the above) | ||
| + | * Merge from -current to 1..n project branches | ||
| + | * Merge from 1..n project branches back to -current | ||
| + | |||
| + | Remember, since Subversion doesn' | ||
| </ | </ | ||