Make a working copy from part of an existing working copy in SVN - windows

I have a working copy of a SVN repository. C:\myrepo on my computer points to https://example.com/svn. It has a subfolder in it, /foo/bar. This folder is really big and it's a remote repository, so checking it out again would take a very long time. I'd like to give my colleague a working copy of just /foo/bar, not the whole repository (because the whole repository is even bigger and contains a bunch of stuff that will confuse them).
I can make a copy of my working copy, C:\myrepo-bar and then use svn switch https://example.com/svn/foo/bar but it says there's no common ancestry (which is true) and so (if I force it) it checks out the whole folder again.
Is there any way to get around this and get a working copy of just https://example.com/svn/foo/bar given that I have a working copy of https://example.com/svn already? I'm using tortoiseSVN but I'm comfortable enough using SVN on the command line.

That depends. In general: no. SVN working copies are not like Git or Mercurial repositories; they do not contain any history or other information that is contained in the repository, only a copy of the selected version of the files.
If, however, you are using an old version of the SVN client, a version old enough to put a ".svn" directory in every subdirectory of your project, then you may be able to just copy the subdirectory (including the .svn directory inside). I'm not sure if this will have consequences with username or whatever, I only ever did that for my own use. And, recent versions of the client have removed the .svn directory from all but the working-copy root, so this is not an option for recent clients.

Related

Checked out a repo from remote but when I do a git status a file shows up as modified — how to fix?

I am using Windows and Git and I had modified a file. No matter how many times I did a git add and commit, the file kept showing up as modified and i could not for example do a git pull --rebase. I assume I did something wrong and screwed up the local Git repo so I decided to clone the repo from github, into a completely new directory. To my surprise, even in this new directory tree when I do a git status the same file shows up as modified -- it is as if it is somehow modified in the github (remote) repo which does not make sense to me. Moreover, the version of the file in cloned local repo does not have the latest version of the code that i can see when i look at the code on github. How can i fix this? I am concerned that someone else cloning the code will end up with the same problem. (Apparently only I am seeing this problem -- I did not somehow manage to corrupt the github repo which leads me to believe this is a git/windows issue.) As far as what I think I did wrong is when I modified a file and did a git add, i misspelled the directory path by using a lower case letter instead of an uppercase and then adding one file resulted in the other, properly spelled path showing up as modified and vice versa. I don't know if a symlink on windows got created -- the file contents are identical. But one would think cloning (via Eclipse) into a completely new directory tree would make this a non-issue.
I looked through replies but it seems like the basic problem is Window's case insensitivity and this caused some (to me) weird behavior. In particular, I simply could not delete one of the folders -- they were "entangled." So the simple solution was to delete the folder and its contents from unix which is case sensitive. Then I checked out a fresh repo and problems appear to be completely resolved.
You mentioned in a comment that you discovered one commit containing two problematic files: one named Login/Login.tsx and one named login/Login.tsx. This comment is on a related question; see my answer there for a discussion of Git's method of naming files in its index, vs what your OS requires in your working tree.
Your solution—use a Unix or Linux machine, where you get a case-sensitive file system, to repair the situation—is probably the easiest and best way to deal with this. If you can establish a case-sensitive file system on your own machine, that also allows easy dealing with this (see my answer to another related question for a macOS-specific way to make a case-sensitive file system).
Given that what you wanted was simply to delete one of the spellings, though, git rm should allow you do that. In particular git rm --cached login/Login.tsx would drop login/Login.tsx from Git's index, without affecting Login/Login.tsx. This could leave your working tree with an existing login folder, though.
It's important—at all times, really, but especially when working within a situation like this—to realize that Git itself doesn't actually need or use your working tree to make new commits. Each commit contains a full snapshot of every file that Git knows about. These files exist as "copies" in Git's index.1 Hence there are actually three copies of each file:
A frozen version of each file appears in the current commit (whatever that commit's hash ID is).
A "copy" (see footnote 1) of that version appears in Git's index. You can replace this copy with different content, and the read-only copy in the commit doesn't change. You can remove this copy entirely, and the read-only copy still doesn't change. Nothing in any existing commit can or will ever change. The index copy exists precisely so that you can replace it, or remove it, or whatever. In effect, the index—or staging area, if you prefer this term—acts as your proposed next commit. It's merely filled in from a commit.
Finally, there's a regular, ordinary, everyday file. This copy goes into your working tree or work-tree. To put this copy in place, Git must use your OS's file-manipulation facilities. That may require creating folders and files within the folders. If those are case-insensitive, and Git goes to create a Login folder when a login folder exists, or vice versa, the OS will say: nope, sorry, already exists. Git will do its best to accommodate the OS by using the "wrong" case anyway, and will create a file within that wrong-case folder—or perhaps destroy some other work-tree file that has the same name except for case, or whatever.
This last bit, where your work-tree files end up with the wrong names and/or in the wrong folders and/or end up overwriting similar files whose name differs in case somewhere, is a problem for you. It's not a problem for Git, though. Git just keeps using the index copies of each file. The next git commit you run uses whatever is in Git's index. The fact that your work-tree doesn't match is not a problem for Git. It's just a problem for you, because the normal everyday git add command means make the Git index entry for this file match the copy that's in my work-tree, and if that's the wrong copy, well, that's a problem.
In any case, once you have a correct commit in Git as your current commit, and extracted into Git's index, you can do whatever you like to your work-tree, including remove large swaths of it, or rename folders, or whatever. Get it set up however you like, then use git checkout or git restore to re-extract all or part of the current commit to your work-tree. Now that you've eliminated the name-case-issues in Git's commit and index, and cleaned up or removed any problematic files and/or folders in your work-tree, Git can create correct-case folders and/or files as needed. It's the process of getting the correct commit into Git that's painful, except on a case-sensitive file system.
1"Copies" is in quotes here because the files in Git's index—which Git also calls the staging area—are in a special Git-only format that de-duplicates content. When the copies that are in Git's index match the copies that are in some existing commit, Git is really just re-using the existing commit's files. Files with all-new content actually require a new internal blob object, which Git creates as needed; after that, the content will be de-duplicated as usual.

SVN - Steps to get all the files from a repository?

We have an existing repository on the network accessed via HTTP:.
Should I first import these files to my local machine? I tried importing directories, files, etc., everything is empty in my local folders. It says "success", but nothing ever shows up!
It doesn't make sense to create a repository on my side. But all the tutorials seem to say that, but then I think they're assuming you're starting from nothing.
My experience with Tortoise SVN has mostly been negative. Typically whatever I think I should do turns out to be incorrect, and I end up having to undo, and redo, or lose my work. Once I even managed to corrupt the main repository and it had to be restored from backup.
I absolutely cannot damage this existing repository!
If you're used to CVS or some older version control systems, note that SVN uses the same terms differently. In those, checkout often means lock in exclusive mode.
In SVN checkout will make a copy and automatically manage the revisions and help you merge from multiple sources. You don't need to lock a file, unless it's graphical or some other binary where merging doesn't make sense.
So in TortoiseSVN, you can checkout, and edit the files. The icons on the files will change to indicate their status.
SVN is easy in comparison to git, where the same terms are again redefined and significantly augmented!

Safely using junction or mklink /j with a git repository on Windows

Using Git on Windows, I'm trying to deal with content that's external to my git repo. We have artwork and content files for instance that are being updated by non git-users in google drive so to capture these changes I've setup something similar to the following;
d:\MyRepo
\.git
\code1
\images1
\fonts (junction) => c:\users\%username%\google drive\designerLtd\fonts
\etc
Where 'fonts' is a folder has been linked using either junction.exe or mklink /j (same thing). This generally works out great because Git status immediately highlights new changes (either on purpose or by accident) and prepares them for checkin or undo.
ISSUE: sometimes when switching branches Git prunes the linked directories and re-creates them if content in those folders is different between branches. In effect it breaks the link. Now Git is always correct and the build is consistent but it's not always obvious that it is no longer keeping track of those external resources.
Worse still, it can delete files in the external location. They can be recovered from git of course, but it's very unwieldy.
Swapping the content in the external locations when branches are switched isn't a problem, because there's only one PC that's hooked up this way and they're easily merged, but I just wish it didn't break the links.
QUESTION: Is there a better way to allow external junction points within a Git repo on Windows?
To be clear, there are no symlinks in the GIT repository (yet) as far as I know and this isn't a question about interoperability between Unix and Windows git clients (which most of the other questions on SO seem to relate to).
You can modify permissions of the junction point so that git can no longer delete it. Git usually doesn't care if removing a directory fails (except if it needs to replace the directory with a file).
See "Usage Recommendations" in https://support.microsoft.com/en-us/kb/205524

Make a SVN working folder identical to repository version

I basically want to do an SVN export as part of a scripted build process, but without having to get the entire repo from scratch every time, which is slow and eats bandwidth... not to mention will make testing the script a pain in the backside if it does this everytime we tweak something or spot a typo in the scripts.
Is there an obvious way to do an export into an existing directory, so only files that are different are fetched, and non-repo files are deleted, basically giving a clean export but done in a smart way?
Windows is preferred, but I guess Cygwin is an option.
I think the only way to get this done, is to checkout a working copy, and update & revert that. Updating a WC only gets the changes.
svn export doesn't know what files are changed, and to compare files, you first have to fetch all of them. Also it would be hard to get files that were deleted or renamed out of your 'export' directory.
Checkout a working copy, then export from your working copy.
SVN update on the working copy will then be quick and bandwitch light.
Then you can delete the original export and re-export from the working copy.
All the bandwidth hungry operations are optimized. The heavy handed delete and re-create is the same as it was before, but it's now all local, so should be much faster.
Also, you have the option to make changes in the exported working copy, but you might want to be careful with that and consider the impact of having conflicts occur during your svn update.
I am not sure if I understand your question right. To rephrase it. I think you would want to have the repo local copy updated on a regular basis. However you would want the working copy pristine so that the resulting build is a clean. Considering this is your question below is what I would suggest.
To my knowledge svn export might not be the be best option for this. Because the purpose of svn export is to obtain a unversioned working copy of the svn repo. As it is unversioned, svn client would not really know from where it has to start the update.
The best option i can think of is this. Checkout the copy of the repo (local copy, LC) in a location. This LC should be updated during the build process. Make a copy of the LC in a different location and use it for performing the build. Below are the commands you would require
1. svn update <arbitrary path>(in the working copy)
2. copy <arbitrary path> <build path>
3. find <build path> -type 'd' -name '.svn' (if you would like to remove the .svn hidden files, but they are not going to really hurt the build process)
Some Options for Eliminating the copy time from factoring in the build process time
If you would like to save the copy time during the build process probably you can do this copy operation after each build and svn update the copy just before building (assume the .svn folders are retained).
On linux two folders can be kept in sync using rsync. The build copy can be made to reflect the updates in the pristine copy.
In Windows, there are a few tools to achieve sync suggested above. I have not used them but I will provide you the links to try it yourself.
http://lifehacker.com/326199/synchronize-folders-with-synctoy-20
http://www.techsupportalert.com/best-free-folder-synchronization-utility.htm
Another option is to use checkout and revert / update but also use something like the SharpSvn library to make a script that will delete non-source controlled files. This way build artifacts like compiled code will be removed and the versioned files will be returned to base state by the revert / update.
If you have a lot of directories and files this scanning could be slow, but if you are confident about what directories will contain build artifacts would can just scan those.

Best approaches to versioning Mac "bundle" files

So you know a lot of Mac apps use "bundles": It looks like a single file to your application, but it's actually a folder with many files inside.
For a version control system to handle this, it needs to:
check out all the files in a directory, so the app can modify them as necessary
at checkin,
commit files which have been modified
add new files which the application has created
mark as deleted files which are no longer there (since the app deleted them)
manage this as one atomic change
Any ideas on the best way to handle this with existing version control systems? Are any of the versioning systems more adept in this area?
Mercurial in particular versions based on file, not directory structure. Therefore, your working tree, which is a fully-fledged repository, doesn't spit out .svn folders at each level.
It also means that a directory that is replaced, like an Application or other Bundle, will still find it's contents with particular file names under revision control. File names are monitored, not inodes or anything fancy like that!
Obviously, if a new file is added to the Bundle, you'll need to explicitly add this to your repository. Similarly, removing a file from a Bundle should be done with an 'hg rm'.
There aren't any decent Mercurial GUIs for OS X yet, but if all you do is add/commit/merge, it isn't that hard to use a command line.
For distributed SCM systems like git and mercurial shouldn't be a problem as Matthew mentioned.
If you need to use a centralized SCM like Subversion or CVS, then you can zip up (archive) your bundles before checking them into source control. This can be painful and takes an extra step. There is a good blog post about this at Tapestry Central:
Mac OS X bundles vs. Subversion
This article demonstrates a ruby script that manages the archiving for you.
An update from the future:
If I recall, the problem with managing bundles in SVN was all the .svn folders getting cleared each time you made a bundle. This shouldn't be a problem any more, now that SVN stores everything in a single .svn folder at the root.
Bringing this thread back to daylight, since the October 2013 iWork (Pages 5.0 etc.) no longer allows storing in 'flat file' (zipped), but only as bundles.
The problem is not the creation of version control hidden folders inside such structures (well, for svn it is), but as Mark says in the question: getting automatic, atomic update of files added or removed (by the application, in this case iWork) so I wouldn't need to do that manually.
Clearly, iWork and Apple are only bothered by iCloud usability. Yet I have a genuine case for storing .pages, .numbers and .keynote in a Mercurial repo. After the update, it blows everything apart. What to do?
Addendum:
Found 'hg addremove' that does the trick for me.
$ hg help addremove
hg addremove [OPTION]... [FILE]...
add all new files, delete all missing files

Resources