📜 ⬆️ ⬇️

Subversion: merging file renames

“Why are you, Squirrel, following me, Boar?”
- I do not know, Boar! Order Ferret. How did you understand? Reception
- Dick did not understand! What ferret, squirrel? I'm a boar. Who is the Ferret? Who is it? Reception
- Boar, you are a woodpecker! How did you understand? Reception
- I understand you, Squirrel. I am a woodpecker. I repeat the question about the ferret. Who is it?
- Boar, bitch, you all lured, fly forward silently! End of communication.
Victor Shenderovich

As you know, Subversion cannot track file renames. According to the documentation, the svn move equivalent to svn copy followed by svn delete . This behavior causes big problems when merging branches. Consider ways to solve them.

In the examples, instead of the full path to the branch, the $source variable is used, which can be created like this:

export source=https://example.com/svn/trunk

The file is renamed in the current thread.


Suppose that in the current branch the file foo.txt been renamed to bar.txt . Let's try to transfer the changes from the $source branch, where the file is still called foo.txt :

svn merge $source -r 10:20
Skipped missing target: 'foo.txt'


Subversion was unable to apply the changes because it did not find the foo.txt file in the working copy. What to do? Explicitly specify the new file name:
')
svn merge $source/foo.txt -r 10:20 bar.txt
U bar.txt


Subversion took the changes in the file foo.txt from 10 to 20 revision, and applied to the file bar.txt , which we wanted.

File is renamed to source.


Suppose that in the $source branch the file foo.txt was renamed to bar.txt . In the current branch, the file is still called foo.txt . In both branches, the files have changed the contents. Let's try to glue the changes:

svn merge $source -r 10:20
A bar.txt
D foo.txt


What happened? Subversion deleted the foo.txt file and added a copy of the bar.txt file from the $source branch. In this case, all changes in the file foo.txt , made in the current branch, were lost .

What to do? First, undo the destructive svn merge actions:

svn revert foo.txt bar.txt
Reverted 'foo.txt'
Reverted 'bar.txt'
rm bar.txt


Secondly, locally rename the file foo.txt to bar.txt :

svn move foo.txt bar.txt
A bar.txt
D foo.txt


Thirdly, to impose on it the changes that have occurred to the file in the $source branch:

svn merge $source/foo.txt@10 $source/bar.txt@20 bar.txt
U bar.txt


Note: we take the difference between the tenth revision bar.txt file bar.txt twentieth revision bar.txt file and impose it on the local bar.txt .

Result: the file is renamed and contains changes from both branches.

File renamed in both branches


Let the file $source foo.txt named bar.txt in the $source branch, and bar.txt in the current baz.txt . In both branches, the files have changed the contents. Let's try to glue the changes:

svn merge $source -r 10:20
A bar.txt
Skipped missing target: 'foo.txt'


Subversion copied the bar.txt file from the $source branch, but failed to remove foo.txt . As in the previous case, we return everything back:

svn revert bar.txt
Reverted 'bar.txt'
rm bar.txt


Further actions depend on which name we think is correct: the current one ( baz.txt ) or $source ( bar.txt ) that came from the branch. In the first case, it is enough to impose the difference between foo.txt and bar.txt on baz.txt :

svn merge $source/foo.txt@10 $source/bar.txt@20 baz.txt
U baz.txt


In the second case, you must first rename baz.txt to bar.txt and only then impose the difference:

svn move baz.txt bar.txt
A bar.txt
D baz.txt

svn merge $source/foo.txt@10 $source/bar.txt@20 bar.txt
U bar.txt


Conclusion


As you can see, merging file renames is not an easy task in Subversion. It can be facilitated by small scripts, the writing of which the author leaves as homework.

Anticipating the holivar on “Which version control system is better”, the author will be grateful for the informative comments on how the task of tracking renamed files is solved in other systems.

Related Links

Source: https://habr.com/ru/post/39230/


All Articles