11

I'm working a shared project using git for version control. I'm on windows while my partner is on Unix.

My partner has named some files with <file1>.txt. When I try to pull these files they are not accepted as the < and > are invalid characters for Windows. This is fine, I don't need to touch the files. However, they are added to my commit as deleted. So, if I push then I'll delete these files which I don't want to do.

  1. I can't use git reset --hard as it finds an invalid path for each of these "deleted" files.

  2. Is there a way to exclude these files from my commits? I've tried adding <file1> to my .git/info/exclude but that didn't work.

hjpotter92
  • 78,589
  • 36
  • 144
  • 183
Nryan6
  • 115
  • 1
  • 1
  • 6
  • 1
    How did those files appear in your commit? Did you do `git commit -a` or `git add .`? Do you want to edit your commit or you want to just remove those files from the index? – Paul Nov 13 '15 at 22:17
  • I'd personally request that the names be changed using `git mv`, and you should be able to perform a forced pull after that, but that is a personal preference. It's the easy solution as it would allow you to edit those files instead of being unable to do anything with them. –  Nov 13 '15 at 23:20
  • Alternatively, do it yourself: install the `git` package (and any of its required dependencies) with the Cygwin installer, navigate to the checkout directory in the Cygwin terminal (e.g. `cd /cygdrive/c/Users/Nryan6/projects/FooBar`), [pull again (possibly overwriting local changes; click for more info)](http://stackoverflow.com/a/8888015/539810), `git mv \.txt file1.txt` (do the same for any other files), and commit and push. Cygwin will translate U+003C (`<`) and U+003E (`>`) to U+F03C and U+F03E, which Windows will allow, but Cygwin will see them as normal `<` and `>` characters. –  Nov 13 '15 at 23:55
  • There are more complicated ways of fixing this, including applying a modified patch after reverting the bad commit(s) or after a hard reset, but using `git mv`, committing the changes, and pushing the changes to the remote is easiest. –  Nov 13 '15 at 23:58
  • You might try adding a gitignore file to your project locally while checking in your changes. Add these files to your .gitignore file. Make sure you don't checkin the .gitignore file to the repo since you dont want your partner's machine to ignore those files. Ref: https://help.github.com/articles/ignoring-files/ – SaurabhM Dec 03 '15 at 18:47

2 Answers2

6

You would need to get your partner to change the names to be something that is also valid on Windows. After they have renamed them, what I'd do is this:

  1. Backup any changes that you only have locally (both uncommitted AND committed but not pushed).
  2. Run git reset --hard <commit> where <commit> is any commit from before the files were added.
  3. Run git pull to get all the way to the latest revision (where the files are renamed).
  4. Restore your backed up changes from 1.

This should then get the newer revision where the files aren't named in this, to Windows, illegal way, and they won't be deleted (or ever created) from under git by the OS :)

P.S. I know this is an old question, but I've been getting this issue recently, so hopefully the solution I've arrived at can help others as well.

EDIT:

To avoid this happening again, your partner can add a pre-commit hook that will stop them from committing files with names that would not be allowed on Windows. There's a sample/example often in pre-commit.sample. I've changed the bit a little in the past and end up with something like:

# Cross platform projects tend to avoid non-ASCII filenames; prevent
# them from being added to the repository. We exploit the fact that the
# printable range starts at the space character and ends with tilde.
if [ "$allownonascii" != "true" ] &&
    # Note that the use of brackets around a tr range is ok here, (it's
    # even required, for portability to Solaris 10's /usr/bin/tr), since
    # the square bracket bytes happen to fall in the designated range.
    echo $(git diff --cached --name-only --diff-filter=A -z $against | LC_ALL=C)
    test $(git diff --cached --name-only --diff-filter=A -z $against |
      LC_ALL=C tr -d '[ !#-)+-.0-9;=@-[]-{}~]\0' | wc -c) != 0
then
    cat <<\EOF
Error: Attempt to add a non-ASCII file name.

This can cause problems if you want to work with people on other platforms.

To be portable it is advisable to rename the file.

If you know what you are doing you can disable this check using:

  git config hooks.allownonascii true
EOF
    exit 1
fi

The '[ !#-)+-.0-9;=@-[]-{}~]\0' bit is the important part that I've changed a little. It defines all the allowed ranges of characters, and the example one only disallows "non-ascii" characters (which is what the comment at the top says), but there are also ascii characters that are not allowed in file names on Windows (such as ? and :).

All the allowed characters are removed, and if there's anything left (wc -c != 0) it errors. It can be a bit difficult to read, as you can't see any of the disallowed characters. It helps if you have a list of the char ranges to look at when reading or editing it.

Svend Hansen
  • 3,277
  • 3
  • 31
  • 50
2

Ignoring doesn't help if the files are tracked already.

Use Sparse checkout to skip those files.

max630
  • 8,762
  • 3
  • 30
  • 55