Yet another Subversion rant
-
I don't trust it. Two of us have been working on the same file today, so we agreed he would check his changes in first and I would update mine, merge and commit the merge. I get the go ahead to update, update tells me correctly that the exact same file we've worked on is conflicted. I look at the file. no "mine" or "r.6271" markers anywhere to be seen, but a load of interface implementations are missing. I update again, to no avail. I stubbed out the interface implementations, compiled, ran all my tests and tried to commit only to be told that my file is out of date and needs updating before I can commit so I update again, and hey presto, a handful of marked conflicts in the same file. Nobody else has committed anything in that time. WTF? Last week our build server failed to get the externals we'd set up on a repository, even though a local update got them all. Cue hours of digging around instead of actually being productive. I really hate SVN.
Please tell us you are not using the file:/// protocol... I have been using Subversion of years. I have run into problems but nothing like you describe. And trust me, we get file conflicts all the time.
-
I don't trust it. Two of us have been working on the same file today, so we agreed he would check his changes in first and I would update mine, merge and commit the merge. I get the go ahead to update, update tells me correctly that the exact same file we've worked on is conflicted. I look at the file. no "mine" or "r.6271" markers anywhere to be seen, but a load of interface implementations are missing. I update again, to no avail. I stubbed out the interface implementations, compiled, ran all my tests and tried to commit only to be told that my file is out of date and needs updating before I can commit so I update again, and hey presto, a handful of marked conflicts in the same file. Nobody else has committed anything in that time. WTF? Last week our build server failed to get the externals we'd set up on a repository, even though a local update got them all. Cue hours of digging around instead of actually being productive. I really hate SVN.
The whole point of version control is to prevent developers from overwriting other developers' source code. Subversion is a complete joke and handling branching and merging is a total nightmare. Simple solution: convert over to an intuitive SCM like git. Once you learn it, all the other solutions become stupid and irrelevant. Ask Linus if you don't believe me. ;)
"God gave us two ears and one mouth to remind us we should listen twice as much as we talk." - Author unknown
-
The whole point of version control is to prevent developers from overwriting other developers' source code. Subversion is a complete joke and handling branching and merging is a total nightmare. Simple solution: convert over to an intuitive SCM like git. Once you learn it, all the other solutions become stupid and irrelevant. Ask Linus if you don't believe me. ;)
"God gave us two ears and one mouth to remind us we should listen twice as much as we talk." - Author unknown
-
I've used SVN a lot...and had many more problems than success with merges (although the later versions are getting better). I've also used mercurial a lot...and can count the number of merge conflicts I've had on the fingers of one hand. Fundamentally, a DVCS like mercurial or git has much better theoretical underpinnings than SVN. Branches are treated as alternate repositories, NOT just as other sub-trees in a file system. So, anyway - use mercurial (or git, I guess, I just have a prejudice against it :-) ), life'll be that much easier...
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p CodeProject MVP for 2010 - who'd'a thunk it!
Stuart Dootson wrote:
a DVCS like mercurial or git has much better theoretical underpinnings than SVN. Branches are treated as alternate repositories
I don't get that. SVN uses one repository, Mercurial/GIT use many repositories - if anything that should increase the number of required merges, not decrease them, no? :confused:
-
Stuart Dootson wrote:
a DVCS like mercurial or git has much better theoretical underpinnings than SVN. Branches are treated as alternate repositories
I don't get that. SVN uses one repository, Mercurial/GIT use many repositories - if anything that should increase the number of required merges, not decrease them, no? :confused:
I stated that badly, I think. What I meant really, is that when you branch in SVN, you're effectively copying the trunk (or whatever branch you're on) to a new location in the SVN repository (although, of course, it's all done with links, really). With Mercurial or Git, you're just adding a label to the current state of the repository that says what branch the revision is at the tip of. And to be honest, the number of merges doesn't really matter so much - it's how well the system can track the changes you've made that's at issue. With SVN, when you do a merge, the merge code in SVN looks at what files each directory sub-tree contains and tries to merge their current states. With Mercurial (or Git), when you do a merge, the merge code looks for the nearest common ancestor changeset between the two revisions you're merging, then (in effect) replays the changes that give the 'other' revision onto the revision you're merging into. And this extends to other repositories - Hg/Git can easily find common changesets between different repositories, because each changeset is identified by a hash (SHA-1, IIRC). The best description I can find of why DVCS's are better at merging than a centralized VCS like SVN is in Eric Sink's book Version Control By Example[^]:
_
- They’re built on a DAG (see Section 4 in Chapter 4). Merge algorithms need good information about history and common ancestors. A DAG is a better way to represent that kind of information than the techniques used by most centralized tools.
- They keep the developer’s intended changes distinct from the merge she had to do in order to get those changes committed. This approach is less error-prone at commit time, since the developer’s changes are already cleanly tucked away in an immutable changeset. The only thing that needs to be done is the merge itself, so it gets all the attention it needs. Later, when tracking down a problem, it is easy to figure out if the problem happened during the intended changes or the merge, since those two things are distinct in the history
- They deal with whole-tree branches, not directory branches. The path names in the tree are independent of the branch. This improves interoperability with other tooling.
_
To show that, try this: 1) Create an empty repository and create a f
-
I don't trust it. Two of us have been working on the same file today, so we agreed he would check his changes in first and I would update mine, merge and commit the merge. I get the go ahead to update, update tells me correctly that the exact same file we've worked on is conflicted. I look at the file. no "mine" or "r.6271" markers anywhere to be seen, but a load of interface implementations are missing. I update again, to no avail. I stubbed out the interface implementations, compiled, ran all my tests and tried to commit only to be told that my file is out of date and needs updating before I can commit so I update again, and hey presto, a handful of marked conflicts in the same file. Nobody else has committed anything in that time. WTF? Last week our build server failed to get the externals we'd set up on a repository, even though a local update got them all. Cue hours of digging around instead of actually being productive. I really hate SVN.
Did you try having WinMerge as a Merge Tool? That helps resolving quite easily.
Vasudevan Deepak Kumar Personal Homepage
Tech Gossips
The woods are lovely, dark and deep, But I have promises to keep, And miles to go before I sleep, And miles to go before I sleep! -
I stated that badly, I think. What I meant really, is that when you branch in SVN, you're effectively copying the trunk (or whatever branch you're on) to a new location in the SVN repository (although, of course, it's all done with links, really). With Mercurial or Git, you're just adding a label to the current state of the repository that says what branch the revision is at the tip of. And to be honest, the number of merges doesn't really matter so much - it's how well the system can track the changes you've made that's at issue. With SVN, when you do a merge, the merge code in SVN looks at what files each directory sub-tree contains and tries to merge their current states. With Mercurial (or Git), when you do a merge, the merge code looks for the nearest common ancestor changeset between the two revisions you're merging, then (in effect) replays the changes that give the 'other' revision onto the revision you're merging into. And this extends to other repositories - Hg/Git can easily find common changesets between different repositories, because each changeset is identified by a hash (SHA-1, IIRC). The best description I can find of why DVCS's are better at merging than a centralized VCS like SVN is in Eric Sink's book Version Control By Example[^]:
_
- They’re built on a DAG (see Section 4 in Chapter 4). Merge algorithms need good information about history and common ancestors. A DAG is a better way to represent that kind of information than the techniques used by most centralized tools.
- They keep the developer’s intended changes distinct from the merge she had to do in order to get those changes committed. This approach is less error-prone at commit time, since the developer’s changes are already cleanly tucked away in an immutable changeset. The only thing that needs to be done is the merge itself, so it gets all the attention it needs. Later, when tracking down a problem, it is easy to figure out if the problem happened during the intended changes or the merge, since those two things are distinct in the history
- They deal with whole-tree branches, not directory branches. The path names in the tree are independent of the branch. This improves interoperability with other tooling.
_
To show that, try this: 1) Create an empty repository and create a f
Stuart Dootson wrote:
when you branch in SVN, you're effectively copying the trunk (or whatever branch you're on) to a new location in the SVN repository (although, of course, it's all done with links, really). With Mercurial or Git, you're just adding a label to the current state of the repository that says what branch the revision is at the tip of.
Actually what you describe for Mercurial/GIT is exactly how the SVN/TSVN documentation describes branching in SVN. The only information stored is the revision number that the branch is based on. So the most recent common ancestor is known.
Stuart Dootson wrote:
- Create an empty repository and create a file called
a
on the trunk (in SVN) or default branch (in Hg). - Create a branch called
test_branch
and make it the current branch. - Rename the file
a
tob
(usingsvn rename
/hg mv
). - Merge
test_branch
back into the trunk/default branch.
With SVN (version 1.7.8), this resulted in two files on the trunk,a
andb
.
I currently use SVN 1.7.1 with Tortoise SVN and cannot reproduce this behaviour. I can still see
a
in the trunk if I go back to an older revision in the repo browser, but I cannot seea
andb
at the same time anywhere. Also, if I have either file in my working copy, updating to a newer or older revision will exchange the file as appropriate. If you use SVN correctly, you should not have or see botha
andb
in any single location. I should mention though that i don't have the command line interface installed, I only apply changes through TSVN, so I am less prone to obscure mistakes due to inappropriate command line parameters. I do agree though that SVN can be fickle with respect to changes applied to a file that has been renamed in another branch. It's very eassy to lose those changes if you aren't careful. The best way is to commit all changes and synchronize all existing branches immediately before and after a rename. But of course that is not very practical ... Since version 1.6 (IIRC) SVN does analyze and keep track of already performed merges in a trunk, so it should be able to recognize the greatest common change set and limit the merge to the change sets not yet applied. It surely could do a better job of -
Stuart Dootson wrote:
when you branch in SVN, you're effectively copying the trunk (or whatever branch you're on) to a new location in the SVN repository (although, of course, it's all done with links, really). With Mercurial or Git, you're just adding a label to the current state of the repository that says what branch the revision is at the tip of.
Actually what you describe for Mercurial/GIT is exactly how the SVN/TSVN documentation describes branching in SVN. The only information stored is the revision number that the branch is based on. So the most recent common ancestor is known.
Stuart Dootson wrote:
- Create an empty repository and create a file called
a
on the trunk (in SVN) or default branch (in Hg). - Create a branch called
test_branch
and make it the current branch. - Rename the file
a
tob
(usingsvn rename
/hg mv
). - Merge
test_branch
back into the trunk/default branch.
With SVN (version 1.7.8), this resulted in two files on the trunk,a
andb
.
I currently use SVN 1.7.1 with Tortoise SVN and cannot reproduce this behaviour. I can still see
a
in the trunk if I go back to an older revision in the repo browser, but I cannot seea
andb
at the same time anywhere. Also, if I have either file in my working copy, updating to a newer or older revision will exchange the file as appropriate. If you use SVN correctly, you should not have or see botha
andb
in any single location. I should mention though that i don't have the command line interface installed, I only apply changes through TSVN, so I am less prone to obscure mistakes due to inappropriate command line parameters. I do agree though that SVN can be fickle with respect to changes applied to a file that has been renamed in another branch. It's very eassy to lose those changes if you aren't careful. The best way is to commit all changes and synchronize all existing branches immediately before and after a rename. But of course that is not very practical ... Since version 1.6 (IIRC) SVN does analyze and keep track of already performed merges in a trunk, so it should be able to recognize the greatest common change set and limit the merge to the change sets not yet applied. It surely could do a better job ofStefan_Lang wrote:
and I suspect the same is true for Mercurial
It is. Beyond Compare 3 does the job for me (in SVN, Hg or Git...)
Stefan_Lang wrote:
I currently use SVN 1.7.1 with Tortoise SVN and cannot reproduce this behaviour...I only apply changes through TSVN, so I am less prone to obscure mistakes due to inappropriate command line parameters.
Well - these are the commands I used - don't think there are any iffy options used...and yes, forward slashes - I use a MinGW bash shell under Windows - much nicer than the Windows command prompt...
svnadmin create /d/svn-repos/test2
svn co file:///d:/svn-repos/test2 test2
cd test2
svn mkdir trunk branches
svn ci . -m "Created structure"
cd trunk
echo "Hello" > a
svn add a
svn ci -m "first"
svn cp . ../branches/test_branch
cd ../branches/test_branch/
svn mv a b
svn ci . -m "Branched"
echo "World" >> b
svn ci b -m "Updated"
cd ../../trunk/
svn update
svn merge --reintegrate ^/branches/test_branchLooking at the output when I re-do these commands, I think that the commit after renaming
a
tob
intest_branch
is where things don't go quite as expected - doesn't seem to pick-up thata
has been deleted. Maybe I needed to commit before doing the rename... When all's said and done, though, it doesn't make much difference. Personally, Mercurial is a better fit for me, my mindset, than Subversion, so that's what I'll use when at all possible...and I'm very pleased to have extensions like HgSubversion[^] and Convert[^] to make the job of migrating from SVN to Hg as painless as possible :-)Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p CodeProject MVP for 2010 - who'd'a thunk it!
- Create an empty repository and create a file called
-
Stefan_Lang wrote:
and I suspect the same is true for Mercurial
It is. Beyond Compare 3 does the job for me (in SVN, Hg or Git...)
Stefan_Lang wrote:
I currently use SVN 1.7.1 with Tortoise SVN and cannot reproduce this behaviour...I only apply changes through TSVN, so I am less prone to obscure mistakes due to inappropriate command line parameters.
Well - these are the commands I used - don't think there are any iffy options used...and yes, forward slashes - I use a MinGW bash shell under Windows - much nicer than the Windows command prompt...
svnadmin create /d/svn-repos/test2
svn co file:///d:/svn-repos/test2 test2
cd test2
svn mkdir trunk branches
svn ci . -m "Created structure"
cd trunk
echo "Hello" > a
svn add a
svn ci -m "first"
svn cp . ../branches/test_branch
cd ../branches/test_branch/
svn mv a b
svn ci . -m "Branched"
echo "World" >> b
svn ci b -m "Updated"
cd ../../trunk/
svn update
svn merge --reintegrate ^/branches/test_branchLooking at the output when I re-do these commands, I think that the commit after renaming
a
tob
intest_branch
is where things don't go quite as expected - doesn't seem to pick-up thata
has been deleted. Maybe I needed to commit before doing the rename... When all's said and done, though, it doesn't make much difference. Personally, Mercurial is a better fit for me, my mindset, than Subversion, so that's what I'll use when at all possible...and I'm very pleased to have extensions like HgSubversion[^] and Convert[^] to make the job of migrating from SVN to Hg as painless as possible :-)Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p CodeProject MVP for 2010 - who'd'a thunk it!
You never created a branch, you only created a copy of a subdirectory that happened to be named
trunk/
. That is why you then had two files rather than one. The problem started when after creating the initial repository structure you forgot to checkout the repository trunk. Instead you kept using the repository top level as if it were the trunk, effectively turning it into the trunk and converting thetrunk/
andbranches/
subfolders into just that: subfolders. You also should have checked out the new branch specifically: you can't work on a branch without checking it out first. The only reason you didn't encounter errors is that you never created one to start with: you only created a new subfolder within your working copy of the repository. -
The whole point of version control is to prevent developers from overwriting other developers' source code. Subversion is a complete joke and handling branching and merging is a total nightmare. Simple solution: convert over to an intuitive SCM like git. Once you learn it, all the other solutions become stupid and irrelevant. Ask Linus if you don't believe me. ;)
"God gave us two ears and one mouth to remind us we should listen twice as much as we talk." - Author unknown
EdReel wrote:
intuitive SCM like git
That's an oxymoron if I've ever seen one :doh: Branches and merging used to be tricky and sometimes painful in older versions of SVN, but since version 1.5 it has improved considerably. If you think it is a nightmare, you haven't looked in the right place or at the right version.
-
You never created a branch, you only created a copy of a subdirectory that happened to be named
trunk/
. That is why you then had two files rather than one. The problem started when after creating the initial repository structure you forgot to checkout the repository trunk. Instead you kept using the repository top level as if it were the trunk, effectively turning it into the trunk and converting thetrunk/
andbranches/
subfolders into just that: subfolders. You also should have checked out the new branch specifically: you can't work on a branch without checking it out first. The only reason you didn't encounter errors is that you never created one to start with: you only created a new subfolder within your working copy of the repository.Stefan_Lang wrote:
You never created a branch, you only created a copy of a subdirectory that happened to be named
trunk/
. That is why you then had two files rather than one.Think again -
svn copy
(orsvn cp
, for short) *is* how you create a branch - look at the relevant part of the SVN red book[^].Stefan_Lang wrote:
The problem started when after creating the initial repository structure you forgot to checkout the repository trunk. Instead you kept using the repository top level as if it were the trunk, effectively turning it into the trunk and converting the
trunk/
andbranches/
subfolders into just that: subfolders.
You also should have checked out the new branch specifically: you can't work on a branch without checking it out first. The only reason you didn't encounter errors is that you never created one to start with: you only created a new subfolder within your working copy of the repository.Ummm - no. By checking out the entire repository rather than just the trunk sub-tree, I implicitly checkout trunk, tags, branches, everything. Anyway - the use of 'trunk', 'branches' and 'tags' is purely a naming convention, not something mandated by Subversion. Subversion exerts an awful lot less control over the way you work than you imply.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p CodeProject MVP for 2010 - who'd'a thunk it!
-
Stefan_Lang wrote:
You never created a branch, you only created a copy of a subdirectory that happened to be named
trunk/
. That is why you then had two files rather than one.Think again -
svn copy
(orsvn cp
, for short) *is* how you create a branch - look at the relevant part of the SVN red book[^].Stefan_Lang wrote:
The problem started when after creating the initial repository structure you forgot to checkout the repository trunk. Instead you kept using the repository top level as if it were the trunk, effectively turning it into the trunk and converting the
trunk/
andbranches/
subfolders into just that: subfolders.
You also should have checked out the new branch specifically: you can't work on a branch without checking it out first. The only reason you didn't encounter errors is that you never created one to start with: you only created a new subfolder within your working copy of the repository.Ummm - no. By checking out the entire repository rather than just the trunk sub-tree, I implicitly checkout trunk, tags, branches, everything. Anyway - the use of 'trunk', 'branches' and 'tags' is purely a naming convention, not something mandated by Subversion. Subversion exerts an awful lot less control over the way you work than you imply.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p CodeProject MVP for 2010 - who'd'a thunk it!
Ok, let me put it that way: the repository root was the root of your working copy. Therefore any change under that root can not be part of a logical branch! A branch requires a complete copy of your working copy directory and file structure, and there is no way to store that inside the repository if you're already at it's root!
-
I don't trust it. Two of us have been working on the same file today, so we agreed he would check his changes in first and I would update mine, merge and commit the merge. I get the go ahead to update, update tells me correctly that the exact same file we've worked on is conflicted. I look at the file. no "mine" or "r.6271" markers anywhere to be seen, but a load of interface implementations are missing. I update again, to no avail. I stubbed out the interface implementations, compiled, ran all my tests and tried to commit only to be told that my file is out of date and needs updating before I can commit so I update again, and hey presto, a handful of marked conflicts in the same file. Nobody else has committed anything in that time. WTF? Last week our build server failed to get the externals we'd set up on a repository, even though a local update got them all. Cue hours of digging around instead of actually being productive. I really hate SVN.
The merge can be really painful, especially when you try to stop it after starting. Suddenly your application can have tons of errors because of the extra lines put into the file by the tool.
-
Ok, let me put it that way: the repository root was the root of your working copy. Therefore any change under that root can not be part of a logical branch! A branch requires a complete copy of your working copy directory and file structure, and there is no way to store that inside the repository if you're already at it's root!
I'm not entirely sure what you mean here, but I don't think this works the way you're thinking. In SVN a branch is nothing more than a directory that happens to be a copy of another directory. A working directory is just a checkout of some subset of the entire SVN repository directory tree. You can do that at any level. I always do my checkouts at the individual branch level (or at the trunk level) but that is not because where checkouts are done matters, but rather because where commits are done from does matter, and I don't want to accidentally commit something from the wrong level and mess up my history.
-
I'm not entirely sure what you mean here, but I don't think this works the way you're thinking. In SVN a branch is nothing more than a directory that happens to be a copy of another directory. A working directory is just a checkout of some subset of the entire SVN repository directory tree. You can do that at any level. I always do my checkouts at the individual branch level (or at the trunk level) but that is not because where checkouts are done matters, but rather because where commits are done from does matter, and I don't want to accidentally commit something from the wrong level and mess up my history.
No, a branch in SVN is not a directory, it is a link! The problem is that everything was performed inside the working directory, i. e. there was only ever one version: copying a directory and a file, renaming it, and chancging it, all was performed within the same working directory. That means everything always was only a single version at any one time! Every command intended for branching was instead interpreted as a physical change of the working directory. There is a subtle distinction in the svn copy command: if you create a copy in the repository, that copy is created as a link, and effectively creates a branch. If you create a copy in the working directory however, it is just that: a copy. Without further information, SVN can not distinguish whether your local copy was meant to be an actual copy or a new branch, so it goes by the obvious interpretation. See http://svnbook.red-bean.com/en/1.1/re07.html[^] The correct command would have been:
svn cp file:///d:/svn-repos/test2/trunk file:///d:/svn-repos/test2/branches/test_branch
And after that the new branch should have been checked out to a separate working directory, e. g.:
cd ../..
mkdir test_branch
svn co file:///d:/svn-repos/test2/branches/test_branch test_branch
cd test_branchThen you could resume your work renaming/changing a, and merging that back to the trunk.
-
Stefan_Lang wrote:
and I suspect the same is true for Mercurial
It is. Beyond Compare 3 does the job for me (in SVN, Hg or Git...)
Stefan_Lang wrote:
I currently use SVN 1.7.1 with Tortoise SVN and cannot reproduce this behaviour...I only apply changes through TSVN, so I am less prone to obscure mistakes due to inappropriate command line parameters.
Well - these are the commands I used - don't think there are any iffy options used...and yes, forward slashes - I use a MinGW bash shell under Windows - much nicer than the Windows command prompt...
svnadmin create /d/svn-repos/test2
svn co file:///d:/svn-repos/test2 test2
cd test2
svn mkdir trunk branches
svn ci . -m "Created structure"
cd trunk
echo "Hello" > a
svn add a
svn ci -m "first"
svn cp . ../branches/test_branch
cd ../branches/test_branch/
svn mv a b
svn ci . -m "Branched"
echo "World" >> b
svn ci b -m "Updated"
cd ../../trunk/
svn update
svn merge --reintegrate ^/branches/test_branchLooking at the output when I re-do these commands, I think that the commit after renaming
a
tob
intest_branch
is where things don't go quite as expected - doesn't seem to pick-up thata
has been deleted. Maybe I needed to commit before doing the rename... When all's said and done, though, it doesn't make much difference. Personally, Mercurial is a better fit for me, my mindset, than Subversion, so that's what I'll use when at all possible...and I'm very pleased to have extensions like HgSubversion[^] and Convert[^] to make the job of migrating from SVN to Hg as painless as possible :-)Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p CodeProject MVP for 2010 - who'd'a thunk it!
For what its worth I found an old installation of the SVN command line client installed on my system (version 1.6.*something*) and tried to reproduce your results. I got to the cp command, and there I got an error message:
C:\Users\Public\Documents\Entwicklung\Projekte\Sandbox\test_svn_3_1_6\trunk>svn
cp . ../branches/test_branch/
svn: Kann Pfad ».« nicht in sein eigenes Kind »..\branches\test_branch« kopieren(can not copy path ».« into its own child »..\branches\test_branch«) While this actually does not come as a surprise to me, it makes me wonder if you did anything in-between that you forgot to mention? I checked the V 1.7 release notes, but couldn't find any indication that the cp command changed, so you should get the same error.
-
For what its worth I found an old installation of the SVN command line client installed on my system (version 1.6.*something*) and tried to reproduce your results. I got to the cp command, and there I got an error message:
C:\Users\Public\Documents\Entwicklung\Projekte\Sandbox\test_svn_3_1_6\trunk>svn
cp . ../branches/test_branch/
svn: Kann Pfad ».« nicht in sein eigenes Kind »..\branches\test_branch« kopieren(can not copy path ».« into its own child »..\branches\test_branch«) While this actually does not come as a surprise to me, it makes me wonder if you did anything in-between that you forgot to mention? I checked the V 1.7 release notes, but couldn't find any indication that the cp command changed, so you should get the same error.
Are you doing this in the repo, or a working copy checked out from the root of the repo? Because that command works just fine for me... Although I think the safest command to use is probably
svn cp ^/trunk svn/branches/some-name
because that operates solely on the repository - you then need to
svn update
your working copy to receive the newly created branch... The^
character is shorthand for the repository root, so you don't need to type the whole URL. But.... all of this is more complex than typinghg branch _some-name_
, so that's why I'll take Mercurial ;-)Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p CodeProject MVP for 2010 - who'd'a thunk it!
-
Are you doing this in the repo, or a working copy checked out from the root of the repo? Because that command works just fine for me... Although I think the safest command to use is probably
svn cp ^/trunk svn/branches/some-name
because that operates solely on the repository - you then need to
svn update
your working copy to receive the newly created branch... The^
character is shorthand for the repository root, so you don't need to type the whole URL. But.... all of this is more complex than typinghg branch _some-name_
, so that's why I'll take Mercurial ;-)Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p CodeProject MVP for 2010 - who'd'a thunk it!
I literally copied the commands you listed (except for the file paths). Also your question shouldn't be necessary: the two arguments were working copy locations*, a repository location must be an URL. I'm not familiar with the syntax you suggested her, using the caret, but if you want to create a branch in the repository, the syntax that worked for me is
svn cp file:///d:/svn-repos/test2/trunk file:///d:/svn-repos/test2/branches/test_branch
* P.S.: You can not directly access the repository directory structure from either the command line or Windows Explorer, nor can you tell SVN to interpret subsequent path arguments as such. That is why "." can only be a working copy location, not a repository location.
Stuart Dootson wrote:
But.... all of this is more complex than typing
hg branch _some-name_
, so that's why I'll take Mercurial ;-)And I use [RMB]-Branch from the TSVN context menu. :)
-
No, a branch in SVN is not a directory, it is a link! The problem is that everything was performed inside the working directory, i. e. there was only ever one version: copying a directory and a file, renaming it, and chancging it, all was performed within the same working directory. That means everything always was only a single version at any one time! Every command intended for branching was instead interpreted as a physical change of the working directory. There is a subtle distinction in the svn copy command: if you create a copy in the repository, that copy is created as a link, and effectively creates a branch. If you create a copy in the working directory however, it is just that: a copy. Without further information, SVN can not distinguish whether your local copy was meant to be an actual copy or a new branch, so it goes by the obvious interpretation. See http://svnbook.red-bean.com/en/1.1/re07.html[^] The correct command would have been:
svn cp file:///d:/svn-repos/test2/trunk file:///d:/svn-repos/test2/branches/test_branch
And after that the new branch should have been checked out to a separate working directory, e. g.:
cd ../..
mkdir test_branch
svn co file:///d:/svn-repos/test2/branches/test_branch test_branch
cd test_branchThen you could resume your work renaming/changing a, and merging that back to the trunk.
No, I think this is still a bit mistaken. When you use "svn cp" you are always creating a "link" in that it doesn't actually duplicate everything and considers the new copy's history to go back and include the original copy's history prior to where they branched apart. If you use the operating system to copy something in the working directory, absolutely, what you're discussing will be the case. You will have simply (as var as SVN knows) just done an "add" to what appears to be some new files. But using "svn cp" creates a copy/branch/tag. And the web page you reference doesn't actually ever back up your claim of their being any difference between pointing the "svn cp" at something local or directly at the repository. In fact, http://svnbook.red-bean.com/en/1.4/svn.branchmerge.using.html#svn.branchmerge.using.create[^] directly says otherwise: "From the repository's point of view, there's really no difference between these two methods." The whole SVN repository structure from root to tip is really just one giant directory tree. That may seem odd, but it is true. You can check out or commit at any level. There are good reasons in practice to check out at the level of a particular branch and also commit at that same level, but you could theoretically have a working copy of the entire repository and use that instead.
-
ryanb31 wrote:
I have used SVN, Source Safe, and TFS source control and none have been perfect when multiple people work on the same file at the same time.
We've had people edit the same file at the same time using SVN without problems... we usually avoid conflicts though, but if they happen they've always been marked properly. I have other issues with svn though, like the confusing and varied ways to branch and merge branches, though once you have the proper steps figured out it goes ok. What I find odd is having multiple people editing the same section of the same file simultaneously, seemingly intentionally. Why would you do that? That's bad communication or organization. Whenever it's happened to us it's been an accident or as a result of bad communication/misunderstanding over who was doing what. If you're using tools that automate code generation, e.g. resource editors, then it's hard to coordinate two people doing it, so two people shouldn't do it simultaneously. I know it was an SVN bug in this case, but even when SVN does things correctly with conflicts it can be a nightmare to sort out.
Look at me still talking when there's science to do When I look out there it makes me glad I'm not you
There must be a way to lock the file to keep others from editing it. I believe that TFS has this ability.