how do I clone files with colons in the filename

If you try doing:

touch "styles-ie (1:12:11 6:02 PM).css"

you will see that you cannot create it on Windows.

Basically, the repo has the file ( the blob and the tree entry ) but you cannot checkout on Windows as git would be unable to create such a file. No other way but to change the filename.


You can clone the repo on a linux environment, tar it up and copy it to windows, and untar it on windows with tools such as 7zip. 7zip will replace the colon with underscore, and preserve all the git information. As long as that file does not change, you'll be all set for a while. Those files tend not to change much anyway (for example, I have a cert file with a colon in the middle).


In support to the answers "using WSL" or "using Linux environment":

Using WSL: (Windows 11)

1. Enable virtualization:

  • in BIOS
  • in Windows ("Turn Windows features on or off" -> "Virtual Machine Platform"/"Windows Subsystem for Linux" -> check)

2. Download and install linux distibutive (e.g. Ubuntu - latest):

  • in PowerShell:

    wsl --install -d Ubuntu

3. Clone repo in WSL linux console

After WSL has been installed - run the application "WSL" - there going to be a linux console available. In that linux console - clone repository as you would normally do**.

** In my case I logged in as root (>sudo su), created ssh keys, added public ssh key to the github repo, navigated to required directory and cloned ssh repo.

As a result, through WSL console I'm able to see files with ":". Through another file managers, consoles (File Explorer, PowerShell, cmd, git CLI) - in place of colons different symbols displayed.


Good news. Technically, the answer to "how do I clone files with colons in the filename" is to simply use "git clone". Luckily it is only the checkout that fails on Windows (even under msysgit) and there is a rather clean workaround for this shown below.

TL;DR

in Git Bash...

git clone {repo URL}
cd {repo dir}
git ls-tree -r master --name-only | grep -v ":" | xargs git reset HEAD
git commit -m "deleting all files with a colon in the name"
git restore .

... and then

  • download the Zip of the whole git repo
  • rename files with colons inside the Zip (without extracting them)
  • extract just those files you renamed
  • add those renamed files to your working directory

For insight into those few steps listed above, please keep reading....

I was able to work around this issue while working with a repo with colons in various filenames. The following worked for me:

  • Do a regular git clone.

$ git clone https://github.com/wdawson/dropwizard-auth-example.git

You should see the following error that notes that the clone succeeded, but the checkout failed.

Cloning into 'dropwizard-auth-example'...
remote: Enumerating objects: 322, done.
remote: Total 322 (delta 0), reused 0 (delta 0), pack-reused 322
Receiving objects: 100% (322/322), 15.00 MiB | 2.88 MiB/s, done.
Resolving deltas: 100% (72/72), done.
error: invalid path 'src/test/resources/revoker/example-ca/certs/root.localhost:9000.cert.pem'
fatal: unable to checkout working tree
warning: Clone succeeded, but checkout failed.
You can inspect what was checked out with 'git status'
and retry with 'git restore --source=HEAD :/'
  • Change directories to the new cloned repo

cd dropwizard-auth-example

  • Check that the git repo working directory is completely empty

ls

  • Run git-status to find that all the files are staged for deletion

$ git status

Output...

On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        deleted:    .gitignore
        deleted:    .travis.yml
        deleted:    LICENSE
        deleted:    NOTICE
        deleted:    README.md
        deleted:    conf.yml
...
  • Revert the staged deletion of only the files that do not contain a colon in the file name.

$ git ls-tree -r master --name-only | grep -v ":" | xargs git reset HEAD

Output...

Unstaged changes after reset:
D       .gitignore
D       .travis.yml
D       LICENSE
D       NOTICE
D       README.md
D       conf.yml
D       java-cacerts.jks
D       pom.xml
D       src/main/java/wdawson/samples/dropwizard/UserInfoApplication.java
D       src/main/java/wdawson/samples/dropwizard/api/UserInfo.java
D       src/main/java/wdawson/samples/dropwizard/auth/OAuth2Authenticator.java
D       src/main/java/wdawson/samples/dropwizard/auth/OAuth2Authorizer.java
D       src/main/java/wdawson/samples/dropwizard/auth/Role.java
...
  • Run git status again to see that only the files that contain a colon in the file name are now staged for deletion. All other files are still showing as deleted, but not staged for commit. This is what we want at this stage.

$ git status

Output...

On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        deleted:    src/test/resources/revoker/example-ca/certs/root.localhost:9000.cert.pem
        deleted:    src/test/resources/revoker/example-ca/csr/root.localhost:9000.csr.pem
        deleted:    src/test/resources/revoker/example-ca/intermediate/certs/intermediate.localhost:9000.cert.pem
        deleted:    src/test/resources/revoker/example-ca/intermediate/csr/intermediate.localhost:9000.csr.pem
        deleted:    src/test/resources/revoker/example-ca/intermediate/private/intermediate.localhost:9000.key.pem
        deleted:    src/test/resources/revoker/example-ca/private/root.localhost:9000.key.pem

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        deleted:    .gitignore
        deleted:    .travis.yml
        deleted:    LICENSE
        deleted:    NOTICE
        deleted:    README.md
        deleted:    conf.yml
        deleted:    java-cacerts.jks
        deleted:    pom.xml
  • Commit all the staged files. That is, commit the deletion of all the files that contain a colon in the file name.

git commit -m "deleting all files with a colon in the name"

  • Restore everything in the working directory.

$ git restore .

  • View all the files. What a beautiful site.

$ ls

Output...

conf.yml java-cacerts.jks LICENSE NOTICE pom.xml README.md src

Once you've deleted the offending files from your working directory...

  • download a Zip of the whole GitHub repo
  • open it up in 7Zip... Don't unzip it ... just open it for editing (to rename files)
  • find the files that have a colon in the name
  • rename each file with a colon replacing the colon with an underscore...or whatever is appropriate
  • now you can extract those files you just renamed
  • copy them into the git working directory

PS: All of the above was done in GitBash on Windows 10 using git version 2.25.1.windows.1. Similar steps can be done via the GUI using TortoiseGit on Windows.