95

How do you add Linux executable files to .gitignore without giving them an explicit extension and without placing them in a specific or /bin directory? Most are named the same as the C file from which they were compiled without the .c extension.

2
  • This is pretty much a duplicate of stackoverflow.com/questions/5711120/… Could merge them. Commented Feb 1, 2015 at 2:03
  • 4
    No, there is a difference between executable files and binary files. I see the need for ignoring both executable scripts and binary files. I don't think this question is a duplicate.
    – Alexander
    Commented Oct 29, 2015 at 10:18

11 Answers 11

63

Can you ignore all, but source code files?

For example:

*
!*.c
!Makefile
2
  • 17
    This throws the baby out with the bathwater. The point of git warning about untracked files is that you don't accidentily forget to git add new files. By just whitelisting .c files and Makefile, it now becomes easy to forget .h files, READMEs, and other files that might be important. I would keep the .gitignore file more conservative, and only add what you know for sure should be ignored.
    – G. Sliepen
    Commented Apr 5, 2021 at 11:12
  • although for me this answer works, Everyone should understand well what @G.Sliepen is pointing. The use of .gitignore is to blacklist not whitelist files.
    – Mahi
    Commented Dec 30, 2021 at 12:08
32

Most developers usually have a build directory in their project where the actual build process in run. So, all executables, .o, .so, .a, etc. are there and this build directory is added into the .gitignore.

17

I would explicitly put them in the project .gitignore. It's not elegant, but I imagine your project doesn't have that many of them.

1
  • 58
    The reason I stumbled upon this question is exactly because it has that many of them. Commented Sep 9, 2017 at 3:30
16

I wrote a script to automatically add ELF executables to .gitignore.

git-ignore-elf:

#!/bin/sh
set -eu
cd "$(git rev-parse --show-toplevel)"
file=.gitignore
new=$file.new.$$
(
if [ -e "$file" ]; then
    cat "$file"
fi
find . -name .git -prune -o -type f ! -name '*.o' ! -name '*.so' \
    -print0 | xargs -0 file | grep ': *ELF ' | sed 's/:.*//' |
sed 's,^./,,'
) | perl -ne 'print if !$already{$_}++' >"$new"
mv "$new" "$file"

Features:

  • starts looking from the top-level folder (might be a misfeature!)
  • ignores ELF files, excluding .o and .so files which can be ignored with a generic rule
  • preserves existing entries in .gitignore without duplicating them

This single-script version is here: http://sam.nipl.net/b/git-ignore-elf-1

Here is a more modular version, which depends on other scripts (git-root, find-elf, uniqo) from the same place: http://sam.nipl.net/b/git-ignore-elf

1
5

ignore all c, c++ executable files save this in .gitignore file this will ignore all files without file extension cause generally there is no file extension of c/c++ executables in linux

*
!*.*
!*/
4

A way of generating differences against your .gitignore in one go from all the executable files from current dir:

find . -perm /111 -type f | sed 's#^./##' | sort | diff -u .gitignore -

this generates a diff meaning you don't lose any manual changes to the file. This assumes your .gitignore file is already sorted. The sed part just strips the leading ./ that find generates.

There's no automatic way to ignore only executable files, so you're always going to have to man-manage the file.

2

If you happen to have a "project" with quite a lot of executables, for instance, a study project where have a lot of small exercises that result get compiled, you can use this single-liner to update your .gitignore:

for f in $(find . -perm /111 -type f | grep -v '.git' | sed 's#^./##' | sort -u); do grep -q "$f" .gitignore || echo "$f" >> .gitignore ; done
1

I don't know, you can add a rule or two, in the Makefile; something like:

$(TARGET): $(TARGET).o
    $(CC) -ggdb -o $@ $^
    @grep $@ .gitignore > tmp || true
    @[ -s tmp ] || echo $@ >> .gitignore; rm tmp

which will append the executable to the .gitignore if it's not already there.

1

All untracked and unignored files or repositories:

git ls-files --others --exclude-standard

Executable files:

find -type f -executable 

add any untracked unignored files that are also executable to .gitignore:

git ls-files -z --exclude-standard --others \
| find -files0-from /dev/stdin -type f -executable > new.$$
[ -s new.$$ ] && ( cat new.$$ >>.gitignore; rm new.$$; git add .gitignore )

or really, just try not to make such a ridiculous mess. Put executables in a bin/ and be done with it.

0

I too was trying to figure out this very question several times. Wanna share a solution that stuck for long. Though I am writing this from the Go perspective, but otherwise I believe this is generally applicable.

First, the observation is that there are much fewer executables (and/or binary) files in typical project, then everything else. Also, worth noting, that the approach to instead explicitly mark source files "to not ignore", and ignore everything else, doesn't work well, because we want our comments and text files, e.g., be git'ed too.

So the solution was to make a convention that executables have .e suffix, and .gitignore has *.e in it.

It is simple, and works well.

1
  • I supposed it does work well. It is nonstandard though, and doesn't work as well as a convention to put all such files in a dedicated directory. Commented May 20, 2021 at 10:05
0

This could help:

file * | sed -n '/text/d;/exec/s/^\(.*\):.*/\1/p'

Basically it search all executable that are not text file, hence binaries. If ELF binaries are wanted, it could be something like:

file * | sed -n '/text/d;/ELF.*exec/s/^\(.*\):.*/\1/p'

And put the result in .gitignore

Not the answer you're looking for? Browse other questions tagged or ask your own question.