Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. Other Discussions
  3. The Weird and The Wonderful
  4. Yet another Subversion rant

Yet another Subversion rant

Scheduled Pinned Locked Moved The Weird and The Wonderful
sysadmincollaborationquestionannouncement
36 Posts 19 Posters 37 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Stefan_Lang

    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!

    T Offline
    T Offline
    Trajan McGill
    wrote on last edited by
    #25

    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.

    S 1 Reply Last reply
    0
    • T Trajan McGill

      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.

      S Offline
      S Offline
      Stefan_Lang
      wrote on last edited by
      #26

      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_branch

      Then you could resume your work renaming/changing a, and merging that back to the trunk.

      T 1 Reply Last reply
      0
      • S Stuart Dootson

        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_branch

        Looking at the output when I re-do these commands, I think that the commit after renaming a to b in test_branch is where things don't go quite as expected - doesn't seem to pick-up that a 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!

        S Offline
        S Offline
        Stefan_Lang
        wrote on last edited by
        #27

        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.

        S 1 Reply Last reply
        0
        • S Stefan_Lang

          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.

          S Offline
          S Offline
          Stuart Dootson
          wrote on last edited by
          #28

          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 typing hg 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!

          S 2 Replies Last reply
          0
          • S Stuart Dootson

            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 typing hg 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!

            S Offline
            S Offline
            Stefan_Lang
            wrote on last edited by
            #29

            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. :)

            1 Reply Last reply
            0
            • S Stefan_Lang

              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_branch

              Then you could resume your work renaming/changing a, and merging that back to the trunk.

              T Offline
              T Offline
              Trajan McGill
              wrote on last edited by
              #30

              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.

              S 1 Reply Last reply
              0
              • Q QuiJohn

                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

                J Offline
                J Offline
                James Lonero
                wrote on last edited by
                #31

                There must be a way to lock the file to keep others from editing it. I believe that TFS has this ability.

                Q 1 Reply Last reply
                0
                • T Trajan McGill

                  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.

                  S Offline
                  S Offline
                  Stefan_Lang
                  wrote on last edited by
                  #32

                  I give up. I'm used to the TSVN documentation which doesn't have a copy command: it only uses a branch command that only works on the repository. Problem solved... There still remain the facts that 1. the way svn copy was used here resulted in an actual copied file rather than a link. 2. I still don't know why the svn copy command listed here doesn't even work on my SVN 1.6 client. I went through each step twice to be sure I exactly reproduced the same steps, but the error message remains. Apparently it does work on the SVN 1.7 client, and I'm too lazy to install that version, so I'm willing to assign this problem to a different cause. But that still doesn't explain that: 3. if I follow the commands provided in the documentation of V 1.7 (copying URLs in the repository rather than directories of a working copy), I end up with only one file, which is the expected result. If the recommended steps in the documentation yield the expected result, but the steps from the outdated documentation does not, what is your conclusion? At this point I am no longer sure if the SVN documentation is accurate or not, or if it fails to point out specific subtleties about recent changes in the svn copy command. I normally only go by the documentation of TSVN which is a much easier read and always delivered the expected results. Or maybe we uncovered a bug in SVN. The only thing we didn't investigate so far, which may be part of this problem, is the fact that the file rename happened before the "branch" was committed to the repository. I know for a fact that SVN 1.4 had severe trouble keeping track of both structural (directory / rename) changes and file changes at the same time. The TSVN 1.4 documentation made a point to always commit a move (or multiple moves) atomically, and not mix them up with preexisting changes. I. e. all local changes should be committed before the move. Maybe SVN still has some trouble with that scenario: copying inside the repository (the now recommended practice) implicitely commits the new branch, so that could explain why this variant doesn't have to cope with the problem of keeping track of changes applied to an already moved file.

                  T 1 Reply Last reply
                  0
                  • S Stuart Dootson

                    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 typing hg 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!

                    S Offline
                    S Offline
                    Stefan_Lang
                    wrote on last edited by
                    #33

                    P.P.S.: using svn copy on URLs implicitely commits the change whereas the version you used still required a commit. You did perform the move efore the commit, so there is a distinct difference between the command sequence that worked for me and yours. Maybe there is a bug: Older versions of the TSVN documentation specifically pointed out that you should commit all local changes before performing a move, because SVN couldn't keep track of the chronological correct order of either change, and thus could mess up the results. I am not sure whether or not the same holds true, but the fact that you didn't arrive at the expected results seems to indicate it still does!

                    1 Reply Last reply
                    0
                    • J James Lonero

                      There must be a way to lock the file to keep others from editing it. I believe that TFS has this ability.

                      Q Offline
                      Q Offline
                      QuiJohn
                      wrote on last edited by
                      #34

                      James Lonero wrote:

                      There must be a way to lock the file to keep others from editing it. I believe that TFS has this ability.

                      SVN didn't used to have that ability, but it does now.

                      Look at me still talking when there's science to do When I look out there it makes me glad I'm not you

                      1 Reply Last reply
                      0
                      • S Stefan_Lang

                        I give up. I'm used to the TSVN documentation which doesn't have a copy command: it only uses a branch command that only works on the repository. Problem solved... There still remain the facts that 1. the way svn copy was used here resulted in an actual copied file rather than a link. 2. I still don't know why the svn copy command listed here doesn't even work on my SVN 1.6 client. I went through each step twice to be sure I exactly reproduced the same steps, but the error message remains. Apparently it does work on the SVN 1.7 client, and I'm too lazy to install that version, so I'm willing to assign this problem to a different cause. But that still doesn't explain that: 3. if I follow the commands provided in the documentation of V 1.7 (copying URLs in the repository rather than directories of a working copy), I end up with only one file, which is the expected result. If the recommended steps in the documentation yield the expected result, but the steps from the outdated documentation does not, what is your conclusion? At this point I am no longer sure if the SVN documentation is accurate or not, or if it fails to point out specific subtleties about recent changes in the svn copy command. I normally only go by the documentation of TSVN which is a much easier read and always delivered the expected results. Or maybe we uncovered a bug in SVN. The only thing we didn't investigate so far, which may be part of this problem, is the fact that the file rename happened before the "branch" was committed to the repository. I know for a fact that SVN 1.4 had severe trouble keeping track of both structural (directory / rename) changes and file changes at the same time. The TSVN 1.4 documentation made a point to always commit a move (or multiple moves) atomically, and not mix them up with preexisting changes. I. e. all local changes should be committed before the move. Maybe SVN still has some trouble with that scenario: copying inside the repository (the now recommended practice) implicitely commits the new branch, so that could explain why this variant doesn't have to cope with the problem of keeping track of changes applied to an already moved file.

                        T Offline
                        T Offline
                        Trajan McGill
                        wrote on last edited by
                        #35

                        Yes, TSVN does make things easier. Given that all the commands in the original scenario were issued from inside the right subdirectories (committing from the wrong level in the hierarchy also can have unexpected results if you want to be able to see history or merge things properly, which is probably why your workflow involving completely separate checkouts is to be preferred), my inclination is to agree with you and say the cause of this almost certainly has to do with the fact that the move happened before the file being moved was committed in the first place. A move is equivalent (according to the docs) to a copy and a delete, but if you're deleting something whose addition was never committed in the first place, maybe it somehow winds up skipping the delete, which results in two files being present once you do an update. I would personally tend to think this is actually incorrect behavior, but maybe whoever designed it has a good reason for that. It definitely is something that could very easily surprise users, even long-time users who failed to remember all the actions they took in a single batch prior to committing, so it is easier not to do things this way. As you say, when you do a copy directly from and to the repository, the commit happens implicitly as part of the execution of the command, and then you don't have to worry about it.

                        1 Reply Last reply
                        0
                        • N Nemanja Trifunovic

                          Git is the worst source control system I've ever worked it. Including VSS.

                          utf8-cpp

                          R Offline
                          R Offline
                          robocodeboy
                          wrote on last edited by
                          #36

                          It depends: having a completely distributed source control system is gold, for me. Which happens also to be blazingly fast, btw. Oh well, whatever.

                          1 Reply Last reply
                          0
                          Reply
                          • Reply as topic
                          Log in to reply
                          • Oldest to Newest
                          • Newest to Oldest
                          • Most Votes


                          • Login

                          • Don't have an account? Register

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • World
                          • Users
                          • Groups