Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Commits to SVN branches affects trunk as well

I have a problem that whenever I make a branch using TortoiseSVN from trunk, ALL commits to that branch also show up in my trunk folder after I do an update, and the other way around.

What I do is:

  1. Branch /trunk to /branches/foo using TortoiseSVN. Select "Switch working copy to new branch/tag" option in the dialog.
  2. Run "Update" in order to get the /branches/foo folder into my working copy, which is rooted at the project directory.
  3. Make a change to a file in /branches/foo
  4. Commit this change
  5. Run "Update" - which results in the same file in my working copy's /trunk folder also being updated with the change made in the branch

How do I break this link - or create a branch without it being linked 1:1 with trunk?

The only solution I've found is to copy the whole trunk folder and add every single file again; though this shouldn't be necessary.

like image 899
Halfdan Reschat Avatar asked Dec 09 '14 13:12

Halfdan Reschat


4 Answers

From your comments on another answer, it looks like you're using SVN inefficiently. I think this is the root of your problem.

It sounds like your working copy is the project root, and on your computer you can see every branch, every tag, and also trunk. When you do an update, you update at the root project, and get every change in every branch.

This is not how SVN was intended to be used.

The intended use, is to check out one working copy per branch of interest. If you're working on trunk, just check out trunk. If you're working on a feature branch, just check out that branch. You can have multiple working copies for multiple tasks.

The way you're doing it now, if your project gets very large with a large number of branches and tags, you can take up gigabytes of space when you check out the top-level folder, and every operation will take a very long time to complete.

Why is this relevant to your problem? Here's what I assume happened:

  1. You branched trunk
  2. You chose to automatically switch your working copy to the branch. This only affected one folder within your working copy. Now your "trunk" folder is not trunk at all, it is actually pointing to your branch. This is obviously going to be confusing later.
  3. You made a change in the "branch" folder and committed it.
  4. You did an "Update" at the top level.
  5. You see your change from the "branch" folder is now in the "trunk" folder as well.

Now, since you chose to switch your trunk folder, "trunk" on your machine is not pointing to the actual trunk folder in your SVN repository. It is pointing to the branch. This is why you see your change in "trunk" on your machine. If you go into the repository browser, I expect you will NOT see your branch change in trunk. If you "switch" your trunk folder back to trunk, you should see your change disappear from trunk on your machine.

To avoid this in the future, either:

  • Change your workflow to the recommended method of working copies that point to a single trunk or branch rather than the entire project. If you do this, choosing that automatic "switch working copy" option is useful, because you can start with trunk, branch it, and continue working on the branch using the same working copy. With this method, you generally "switch" an entire working copy to a new location, rather than single folders within a working copy, to avoid confusion. OR
  • Continue doing what you're doing, checking out the entire project. Never switch anything in your working copy, because if you do the folder will not be pointing where you expect. In this method, "switch" can only cause confusion. After you branch from trunk, you must update to see the branch, and then go find that branch and start your work there. Hope that your project never gets big enough to eat your entire hard drive, or start using sparse checkouts if it threatens to do so.
like image 191
Ben Avatar answered Oct 10 '22 12:10

Ben


Ben and David W postings are superb...thanks to both of them! Their explanations really helped me understand how trunk, tags, branches can exist on the SVN server and on an SVN client. To add to this, I have a few scenarios that reflect the answers above and provide additional workflow approaches.

Scenarios below show the local folder structure and associated SVN commands on that folder (indented folders are subfolders). Also, I show only trunk and branch folders for brevity (tag folders not shown)...tag folders can be added and treated exactly the same as branch folders for the sake of this discussion.


Scenario A

This is how the O.P. seemed to be using SVN:

Project         << svn co http://server/svn/Project
    trunk
    branches
        branch1
        branch2

...this checks out a complete copy of the entire repository (trunk plus all branches plus all tags). Doing an "svn switch" rooted at any subfolder besides "Project" would cause confusion because the (original) "working copy" is already at "Project" and you would end up with two working copies at two different folders in the same tree. Thus, Ben's advice above to never switch makes sense. Nonetheless, if you never switch (subfolders), it's perfectly valid to use this workflow.


Scenario B

This is what Ben discusses above ("change the depth where you grab your checkout"):

...if you want to work on the trunk:
Project         << svn co http://server/svn/Project/trunk
...if you want to work on branch2:
Project         << svn switch http://server/svn/Project/branches/branch2

...so one folder ("Project") changes its context over time because you do an svn checkout or an svn switch to a different URL each time. But knowing the working context of the local folder is not immediately obvious. In TortoiseSVN, you can right-click and select "Switch" to review the current URL (then cancel the switch) or use "svn info" from command-line, but these are extra steps. Nonetheless, it sounds like this is a very common way to use SVN.


Scenario C

This is a variant of Scenario B which David W discusses above...this approach makes it more obvious (visually) which trunk/branch/tag is being worked on:

Project_trunk     << svn co http://server/svn/Project/trunk
Project_branch2   << svn co http://server/svn/Project/branches/branch2

...and never do an svn switch on the above local folders, since that would cause confusion (e.g. issuing "svn switch http://server/svn/Project/trunk" on Project_branch2 would make the local branch2 folder hold the contents of the repo's trunk). Anyway, this approach does make it immediately visually obvious what your local folder contains.


Scenario D

This is a hybrid of Scenarios A and C and it envelopes all trunk/tags/branches under a top-level folder with the project name, mimicing the structure on the repo:

Project           << (no SVN checkout performed on this folder)
    trunk         << svn co http://server/svn/Project/trunk
    branches      << (no SVN checkout performed on this folder)
        branch1   << svn co http://server/svn/Project/branches/branch1
        branch2   << svn co http://server/svn/Project/branches/branch2

In this approach, you avoid grabbing the entire repo by avoiding the SVN checkout on "Project", and you avoid grabbing all branches by avoiding the SVN checkout on the folder "branches". So it is a selective checkout of branches or trunk just like Scenario C but it still mirrors the repo's structure as in Scenario A. I present this because this is one of the first ways I was visualizing the local structure (as a mirror of the remote structure for consistency). I like how it mirrors the structure on the repository, but it is debatable if this provides more clarity in a workflow since you have to remember "special rules" to avoid checkouts and switches on the folders "Project" and "branches".

My (opinionated) conclusion is that the most obvious workflows are B and C above since they have no special cases that have to be remembered, but A and D can certainly be used if that suits you. Regardless, walking through these scenarios helped me to visualize and understand how to handle trunk, tags, and branches. Hope it helps others!

like image 42
rob_7cc Avatar answered Oct 10 '22 11:10

rob_7cc


I think you're misunderstanding how Subversion (especially TortioseSVN) works.

In Subversion, when you do a checkout, you create a working directory. When you do your update on that working directory for your branch, you're changing that working directory to your branch (if I understand your workflow). The trunk isn't getting changed, just your working directory.

One of the advantages of Subversion is that it's easy to have multiple working directories. (You can in Git, but you end up with multiple copies of your entire repository). So, do a separate checkout for each and every branch. I have a directory I call workdir, and under that, I have all of my branches each in it's own directory (workdir\trunk, workdir\foo, etc.) This way, I don't get confused which branch or trunk is in my working directory.

like image 2
David W. Avatar answered Oct 10 '22 11:10

David W.


Everytime that you create a Branch in Tortoise it asks you if you want to switch to the branch or keep in the trunk, if you not switch all the changes that you are commiting will still be commited to the trunk..

And also, Update will update your local files with the server version, and commit will send your files to the server (both to the selected server folder, trunk or one of the branchs if you switched to it)

like image 1
Gustavo Laureano Avatar answered Oct 10 '22 10:10

Gustavo Laureano