1

As the title says. I want git to refuse to add files which contain spaces in filenames. Is there a config which enforces this?

Vroomfondel
  • 2,704
  • 1
  • 15
  • 29
  • 1
    Write a [Git Hook](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks). – fredrik Aug 20 '20 at 12:55
  • @Vroomfondel Putting a nail through a wooden plank with a screwdriver is possible, but a hammer would be better suited for the task. git is not *meant* to enforce filenaming policy. @fredrik Which hook? `pre-commit` I guess? Wouldn't trigger at `add`, but close enough. – Romain Valeri Aug 20 '20 at 12:57
  • @RomainValeri That's were I would put it - since there is no hook on add. Depending on which remote software is used (if any) I'd put one there on one of the receive hooks as well just in case some dev didn't add the local hook. – fredrik Aug 20 '20 at 13:00
  • @RomainValeri I see no other screwdriver, much less a hammer that would help to educate users to name their files properly. We are using `git` for the electronics guys to store their files and `add` is the earliest point where I can have a look at the filenames they chose. – Vroomfondel Aug 20 '20 at 13:03
  • @Vroomfondel Fair enough, but I had to point it out. Hope it'll work for you. – Romain Valeri Aug 20 '20 at 13:11
  • @RomainValeri If you have some convincing second route to this, I'm all ears! – Vroomfondel Aug 20 '20 at 13:45

2 Answers2

3

The regular expression of **\ ** can be used in the .gitignore file for rejecting file names with spaces.

Here is the demonstration of a working example:

Step 1: Add **\ ** to .gitignore file in the repository

$ my-repository (master)
$ ls
core/  it.tests/  pom.xml  README.md  ui.apps/  ui.content/

$ cat .gitignore
**/.classpath
**/target
**/node_modules/
/node_modules/
/build/

**\ ** 

          ---> Ignore file that has blank spaces in the name

Step 2: Create a file with blank spaces in the name (Example: x y z.txt)

$ echo "Hello! How are you doing?" > "x y z.txt"

$ ls
 core/   it.tests/   pom.xml   README.md   ui.apps/   ui.content/

 'x y z.txt'

Step 3: Try to add the file with spaces in name to the repository and commit

$ git add .

$ git commit -a

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

nothing to commit, working tree clean

Result:

The pattern of **\ ** in .gitignore file prevents the file with blank space in its name from being added to the repository.

More information on .gitignore file:

https://git-scm.com/docs/gitignore

Gopinath
  • 4,066
  • 1
  • 14
  • 16
  • Step 3 is misleading, since it only mentions `git add .`! It is important to realize that `git add specific_file.txt` *ignores* `.gitignore`. Isn't that ironic? Don't you think? – David J. Sep 04 '21 at 14:52
  • A `.gitignore` file does _not_ prevent files from being *committed*; rather, it prevents untracked files from being tracked. Note that `git add foo.txt` will *always* succeed in adding to the index, regardless of the the contents of `.gitignore`. – David J. Sep 04 '21 at 14:57
  • For completeness, I will add this: once a file is tracked, it can be be committed with `git commit bar.txt` -- regardless of `.gitignore`. – David J. Sep 04 '21 at 14:58
  • @DavidJ.`git add` now checks for explicit adds of ignored paths and complains. You can still make it add them, but you have to `-f`orce it now. – jthill Sep 04 '21 at 15:30
  • @jthill Are you sure? What version? I tested with Git 2.30; the newest is 2.33. I searched through the release notes with but didn't find a mention of a `git add -f` option. [I didn't find reference to it in the release notes.](https://github.com/search?q=%22git+add%22+repo%3Agit%2Fgit+extension%3Atxt+path%3A%2FDocumentation%2FRelNotes&type=Code) – David J. Sep 04 '21 at 18:39
  • Just built 2.30.0, tried `./git --exec-path . add git` and it refused to add it because the binary's ignored. So I don't know what you're trying. Then built 2.20.0, that also rejected the add. – jthill Sep 04 '21 at 18:55
-3

I want git to refuse to add files which contain spaces in filenames.

What you are asking, effectively, is how to prevent certain files from being added to the index. What you specifically request is not currently possible using Git hooks.

Perhaps you would like to request a pre-add hook? This seems reasonable to me, and you are not the first to ask for it. I recommend engaging with the Git community to discuss further.

Near-term / priorities

Now, if you want to solve your problem in the near-term, I suggest we step back. Is one of the following goals important than the other?

Preventing a file from being ...

  1. ... added to the index? (git add)

  2. ... committed to the repository? (git commit)

Refuse to commit

From what I can tell, blocking a commit is the core requirement here.

So, going forward, this answer interprets the question as: "I want git to refuse to commit files which contain spaces in filenames.

I see two families of answers: (a) the commonly-used answers and (b) less-common answers

Commonly-used: pre-commit hooks

Practically, I recommend using a Git pre-commit hook:

The pre-commit hook is run first, before you even type in a commit message. It’s used to inspect the snapshot that’s about to be committed, to see if you’ve forgotten something, to make sure tests run, or to examine whatever you need to inspect in the code. Exiting non-zero from this hook aborts the commit, although you can bypass it with git commit --no-verify. You can do things like check for code style (run lint or something equivalent), check for trailing whitespace (the default hook does exactly this), or check for appropriate documentation on new methods.

I see two approaches:

  1. shell (no additional dependencies): The open source GitHooks documentation has an example pre-commit shell script.

  2. a framework: I recommend pre-commit. (This is not included with git.)

pre-commit: A framework for managing and maintaining multi-language pre-commit hooks

Why was the pre-commit framework created?

As we created more libraries and projects we recognized that sharing our pre-commit hooks across projects is painful. We copied and pasted unwieldy bash scripts from project to project and had to manually change the hooks to work for different project structures.

Less-common approaches

  1. If you have control over the environment, you might consider writing your own wrapper on top of git add.

  2. See How to automatically invoke a script before a git add? for discussions of (a) smudge and clean; (b) git-gulp; (c) possibly others that get added over time.

Why .gitignore will not work cannot prevent commits

Updates: I added strikethrough text to indicate where I was wrong in my previous edits. Corrections and changes are called out in bold italics.

  • A .gitignore file does not prevent files from being committed; rather, it prevents untracked files from being tracked.

  • git add file.txt will always succeed in adding file.txt to the index, regardless of the the contents of .gitignore

  • Correction: git add file.txt will warn if file.txt matches a pattern in .gitignore

  • Clarification: git add -f file.txt will always succeed in adding file.txt to the index, regardless of the the contents of .gitignore

  • Addition: Because of the git add -f command, you can see that .gitignore can only warn, not prevent, files from being added to the index (aka staged). Once a file is staged, it is trivial to commit. Therefore, in the context of this answer, where the goal is to prevent commits (see above), .gitignore is not adequate.

  • Once a file is tracked, it can be committed staged with git commit file.txt -- regardless of .gitignore.

  • To elaborate: Once a file is tracked, it can be be staged with git add file.txt and committed with git commit -- regardless of .gitignore.

David J.
  • 31,569
  • 22
  • 122
  • 174
  • For me the `.gitignore`solution seems to work: `$ git add a\ file\ with\ spaces.txt` `The following paths are ignored by one of your .gitignore files:` `a file with spaces.txt` What do I overlook? – Vroomfondel Sep 07 '21 at 09:31
  • @Vroomfondel Yes, you are correct. I updated my answer with corrections and elaborations. Let me know if you have further questions or comments. – David J. Sep 08 '21 at 00:01
  • I noticed some downvotes -- fair enough, since there were some errors. So I've edited and improved my answer. If you find further mistakes (or want to make suggestions) please let me know. – David J. Sep 08 '21 at 00:06
  • The downvote was not from my side. I hope they get corrected. – Vroomfondel Sep 08 '21 at 10:03