I want to export only changes (files and folders - tree) between HEAD and PREVIOUS revisions using svn export command. Is it possible? How to do it under Windows (command-line)?
svn diff -rPREV:HEAD --summarize
Will give you a list of files modified. You should be able to iterate over the list with whatever scripting languages you have available and create the necessary directories followed by svn cat commands to get the contents of each file.
This would be quite easy in bash, maybe someone else can tell you where to go from here in Windows.
Related
Our team works on repository which includes one directory where there are files with pipe character "|". I'm the only one on Windows so pipe character is illegal for files names.
Is there a way to rename files in the directory "extra" from ex. "2021|08|05" to "2021\08\05" when I make "git pull"?
Is there a way to rename files in the directory "extra" from ex. "2021\08\05" to "2021|08|05" when I make "git push"?
No.
No.
These are the right answers to the question you've asked, but the trick is, you've asked the wrong question. Alas, the answer to the right question is: "yes, but it's a horrible solution". The question is: Is there a solution to the problem of bad / invalid characters in file names stored in Git commits?
In the early days of Git, when it was a collection of shell scripts that only a few people could use successfully, 😀 one would obtain new commits from elsewhere with git fetch, then read these commits into Git's index with git read-tree.
Git's index, which Git also calls the staging area or sometimes the cache, can hold these file names. In fact, even on Windows, Git's index can hold files named aux.h, which Windows won't let you create. The index has no folders either: it just has files with names with embedded (forward) slashes, such as path/to/file. Git can hold two different files, one named README and one named readme, in its index. WIndows can't have two different files whose name only differs in case.
So, Git's index / staging-area can hold these files just fine. The problem comes when you go to work with the files. Files that are in Git's index, are stored there in a special Git-only format, as what Git calls a blob object. You cannot read or write a blob object directly. You have to use yet more Git commands to do this. It's terribly inconvenient.
To use Git conveniently, then, we normally don't use all the individual one-step-at-a-time internal Git operations: we use some sort of higher level, user oriented command, like git checkout. We check out an entire commit: Git will find all the files that are stored in that commit, read them into Git's index, and copy out and expand all the internal Git-only blob objects into ordinary files, with ordinary file names.
This step—copying files out of Git's index, to make them usable—is where things go wrong, on Windows. The file's name in Git's index is, say, path/to/2021|08|05. Git recognizes that path/to/ has to be turned into two folders, path\ and path\to\, on Windows, so that Git can create a a file in the second folder. Unfortunately, Git has no way to remap the 2021|08|05 part. That part is going to stay 2021|08|05, and as you have seen, Git can't create a file with that name: the OS just says "no".
What you can do, at this point, is drop down to those lower-level commands. You can run:
git rev-parse :path/to/2021|08|05
perhaps with quotes if needed, depending on your shell:
git rev-parse ":path/to/2021|08|05"
This git rev-parse command will show the blob hash ID for the file. You can then access the file's contents with:
git cat-file -p <hash>
which prints those contents to the standard output. If your shell supports redirection, you can then redirect the output to a file whose name is your choice. This lets you see and use the file's contents.
The git cat-file -p command can take the index path name directly, so:
git cat-file -p ":path/to/2021|08|05" > path/to/2021-08-05
is a way to extract the file to a usable name.
Unfortunately, git add—which is how you would normally update the file—will insist on using the name you gave the file in the file system. Once again, you must fall back on internal Git plumbing commands to work around this. If you need to update that particular file, for instance, you would:
run git hash-object -w -t blob path/to/2021-08-05 to turn the updated file's data into an internal Git object;
run git update-index with arguments to make Git update the entry for path/to/2021|08|05 using the hash ID obtained in step 1.
Once all of this is done, you can go back to normal Git commands, because git commit makes a new commit from what's in Git's index / staging-area.
The (rather large) drawback here is that you cannot use a lot of normal everyday Git commands:
git pull is often a no-go because it runs git rebase or git merge, both of which need to use your working tree (OS-level files). Run git fetch first, then do as much manual work as needed.
git checkout will fail: you can use it, but then you must manually do something about each of the bad file names that are now in Git's index.
git diff will show differences that include deleting the files with the bad names, and git status will show the adjusted-name files as untracked files (because they are).
git add of any changes you need to make to these files is also a no-go; use git hash-object -w and git update-index instead.
git rebase and git merge become difficult. You probably can deal with them as in steps 2 and 4, but that's painful at best.
I'm working on a python project and want to rename a (package) folder to small letters, let's say from Myackage to mypackage. As git is case-sensitive and Windows is not, I followed the solutions taken from here and espacially here.
My procedure was as follows:
git mv Mypackage tmp
git mv tmp mypackage
git commit -m "Change capitalization of package name"
This changes the folder Myackage to mypackage with success (for both, git and Windows). But if I switch to another branch, I expect the folder to change back to Mypackage (with capital letter!), as it was before. Background is, that all the imports of the package are also case-sensitve in python and i need this renamng acompanied with adaptions of the imports.
I've tried both, core.ignorecase set to true and false, but no matter what I try, if I checkout an older branch, the folder remains in form of small letters (mypackage) and I run into issues within python.
UPDATE:
I've set up a small example with only one Folder and one file and could succesfully change the capitalization of the folder. It also shows the desired behaviour, that upon branch switch the capitalization of the folder in Windows changes, yet still this won't work for my python project.
Could it be, that, e.g., submodules, play a role here?
UPDATE 2:
I've checked the case sensitivity attribute for both cases via:
fsutil.exe file queryCaseSensitiveInfo .
Both folders claim, that case-sensitivity is deactivated. Still for one project folder name capitalization changes, but for the other folder not.
The attribute case sensitivity is available on Windows 10 but after April 2018 Update and only affect the specific folder to which you apply it. It isn’t automatically inherited by that folder’s subfolders. However, if you use WSL to create folders it's enabled by default and available in that way to Windows. [1]
Although you can use the Git Unite [2] tool to match the case of the current folders with the git index.
If you use the rename approach, try using it with git commands like in "Rename files and folders with git"[3]
git mv foldername tempname && git mv tempname folderName
I found a way to reproduce your behavior :
if my CaSeD folder contains some extra files (untracked files for example), git will not change the case of my folder name when I jump between commits.
Is this the case in your setup ?
If this is your issue : you could go with a post-checkout hook, which forcibly renames the folders according to what is stored in HEAD after a checkout.
One way to get the full list of paths to directories from commit HEAD is :
git ls-tree --name-only -d -r HEAD
If you match this list with a similar list extracted from your local file system (ls -r ? find . -type d ? some python function from os.* ?), you can spot what folders need to be recapitalized.
I have been trying to write an stcmd that checks out code from a StarTeam repository. Here's what the command looks like:
stcmd co -p "Username:Password#localHost:1024/Store Server/Store Server/USB/sources/$OEM$/$$/Setup/Scripts"
Every time I run this code, I get the following response:
C:\StarTeam\Store Server\USB\sources\$OEM$\$$\Setup\Scripts\osConfig.ps1 (The system cannot find the path specified)
I'm guessing I need to have to create the working folder's location in order for my check-out command to work properly. Is there a way to create the working folders of a repository using stcmd? I know I can do it through StarTeam, but I wanted to see if it's possible to create it through stcmd so it can create the folders on new computers when my code runs.
You haven't said which version you're using, but in 5.4 the command to create working directories is:
stdcmd local-mkdir
so you'd need something like:
stdcmd local-mkdir -p "Username:Password#localHost:1024/Store Server/Store Server/USB/sources/$OEM$/$$/Setup/Scripts"
This is the answer to your question, but I'm not sure it'll be the solution to your problem!
Not sure which version of StarTeam you're using, but in 13.0 at least, there's an option -cwf (checkout working folders) which you can append to the check-out command. if you also want this to checkout subfolders of said working folders, you can also append -is (include subfolders, maybe?). So, try:
stcmd co -p "Username:password#localHost:1024/Store Server/Store Server/USB/sources/$OEM$/$$/Setup/Scripts/" -cwf -is
I have a MacVim setup on my OSX machine so that the default Vim application (ie: /usr/bin/vim) is actually a symbolic link to the command-line version of Vim that ships with MacVim (ie: /Applications/MacVim.app/MacOS/vim), as it provides some key benefits over the stock Vim that ships with OSX10.6.
I periodically need to prepare a diff between a set of files, and export it into a colorful side-by-side-view HTML file. This is commonly achieved via:
vim -d file1 file2
(Within Vim): toHTML
The problem with this is that I have to manually check out the HEAD revision and a specific revision of the two sets of files, and do this operation for each pair of files. This is very time consuming.
Is it possible to have the results of svn diff command piped into Vim so I can have a colorful side-by-side-view diff for an entire directory (ie: the PWD), as opposed to just the unified diff view?
I have found several Vim scripts and bash scripts that attempt to achieve this, but there are two key problems:
I wish to explicitly call vim -d as the diff tool, and not vimdiff, as the MacVim application does not appear to ship with vimdiff, so I would be using the wrong version of Vim when launching the application
I wish to have multi-file diffs generated against an entire directory recursively, as opposed to just one or two files at a time.
If this is not feasible, I could likely create a bash script that more-or-less achieves this, but I'd like to avoid putting together a hacked/unreliable script if there is a more effective means of doing this.
Thank you.
vimdiff is merely an alternate name for vim. The binary checks to see how it's launched and determines its behavior accordingly. (That's why there isn't a different file for gvim and vim also.)
On my Mac OS and Linux machines I created a ~/bin directory, and then inside it created soft-links from the various names to my macvim binary. I put ~/bin very early in my path.
I'm not at work where I could check to make sure, but I think you can change the default SVN diff to point to vimdiff in ~/.subversion/config. Look for the diff-cmd section. https://stackoverflow.com/a/9604604/128421 might give you some useful information too.
You can try my aurum plugin, it ships with :AuVimDiff command which is as well capable of viewing all changes in a multiple tabs with vimdiff split:
AuVimDiff full HEAD 300
and get diffs between two revisions without you having to checkout them manually:
AuVimDiff file file1 HEAD 300
(file file1 part is optional, it will open diffsplit with current file if omitted. All revisions are also optional, for subversion specifying one revision is diffing it with file in the working directory and specifying no revisions is like svn diff: between BASE and working directory.)
300 here is just an example revision.
I have since resolved this fully in another, more recent post of mine. Posting a backtrack URL to it for future readers:
VIM - Passing colon-commands list via command-line
This question already has answers here:
How to make git ignore changes in case?
(6 answers)
Closed 10 months ago.
There are a couple of files in our git-controlled codebase that I'd like to rename. Specifically, I just want to change the case of the file, so that sourceCode.java becomes SourceCode.java, for example. The catch: I'm on a Windows box, and the filesystem thinks those are the same file name.
How can I get Windows and Git to recognize that change and check it in?
The change of the file name should not be ignored, but committed to git.
To rename the file you can use the standard git mv command.
Since Windows treats files with only changes in case as identical, you have to pass the -f option to force a rename:
git mv -f name.java Name.java
If instead you want to ignore case changes, have a look at the question
How to make git ignore changes in case?.
If you are on a FAT file system your only choice is to do a two stage rename:
Rename sourceCode.java to anything.you.like
Rename anything.you.like to SourceCode.java
Back in the days when we used Perforce we had exactly this problem and this was the only solution we could come up with.
The following steps allowed me to change the case on Windows:
Add ignorecase = false to [core] in .git/config;
Move the files you are going to rename out of your project directory;
Add the deletes to the index;
Move all files back to their original location and change the case of the files and/or directories;
Add all "new" files to the index;
Remove ignorecase = false added at the first step.
This way you have a single commit that contains the rename and it makes it easy to change e.g. an entire directory.
In my opinion one simple way is missing. You can do this for a single file, a specific directory or even the whole repository. Just rename your files in any way you like before and than execute these commands:
git rm --cached <file name or directory>
git add <file name or directory>
If you want to affect also the sub-directories, you have to use the -r flag:
git rm -r --cached <directory>
git add <directory>
Be careful. Doing this can lead to changes that are impossible to merge. Git gets confused when merging on Windows because it can't decide whether the old Uppercase name and the new lowercase name are the same file or not (for Git they are not, but for the filesystem they are). To merge you have to do some manual workaround like deleting the files before merging.
See Git rebase issue with files of same name but different case
I'm not sure if this issue is worse than having an unconventionally-named file in your project for ever and ever, but it is worth knowing about if there are lots of users with lots of branches which will all need to be merged eventually.
With NTFS (or FAT), a single git mv command does not solve the problem.
This question shows a technique that works:
git mv and only change case of directory