2

I have some files, for example one being error_log and some of these may have accidentally been added to git before they were added to the .gitignore file so I am wondering how can I delete all instances of files with this name from a Git repo?

Note that I want them left on the server so I would be using the --cached option.

Brett
  • 19,449
  • 54
  • 157
  • 290
  • 1
    It's not clear from your question: do you want to delete the file from the entire commit history or only not to track it in the future? Two different cases, see 2 answers below. – John_West Mar 18 '16 at 11:17
  • Sorry, my main issue was just not tracking it in the future. Removing it altogether doesn't matter either way really. – Brett Mar 18 '16 at 11:20

3 Answers3

2
find -name "error_log" | xargs git rm --cached

Should do the trick

blue112
  • 52,634
  • 3
  • 45
  • 54
  • It affects only the current state of repo, forces not to track "error_log" – John_West Mar 18 '16 at 11:10
  • I'm sorry I accidentally tagged this as Linux as my server is linux based but I'm doing this on my dev machine, which is Windows. – Brett Mar 18 '16 at 11:21
  • Will work under `git bash`. If "error_log" is in your repo's root folder you can just use `git rm --cached error_log` – John_West Mar 18 '16 at 11:26
  • `fatal: pathspec './public_html/error_log' did not match any files` – Brett Mar 18 '16 at 12:49
0

You should use filter-branch to wipe it completely from your commit history (all commits):

git filter-branch --index-filter --prune-empty "find . -name error_log | xargs --no-run-if-empty git rm --cached --ignore-unmatch"

(Solution 5 from here or GitHub's remove sensitive data)

Note! You will loose all you old revisions of "error_log" this way! Only the file in its last state would be available. If you want just to exclude file from repo not to track it in the future use @blue112 's answer

Community
  • 1
  • 1
John_West
  • 2,239
  • 4
  • 24
  • 44
  • I'm sorry I accidentally tagged this as Linux as my server is linux based but I'm doing this on my dev machine, which is Windows. Not sure if this will work on Windows? – Brett Mar 18 '16 at 11:21
  • Will work under [git bash](https://git-for-windows.github.io/) that is the default way to use `git` under `windows` – John_West Mar 18 '16 at 11:24
  • Not sure if it matters or not, but got the warning: `WARNING: Ref 'refs/heads/master' is unchanged` after running this command. – Brett Mar 18 '16 at 11:29
  • It's because your `error_log` is [not under repository root folder](http://stackoverflow.com/a/12149964). 've changed the answer to reflect this. – John_West Mar 18 '16 at 11:32
  • Got this: `index filter failed: find -name "error_log" | xargs git rm --cached --ignore-unmatch` – Brett Mar 18 '16 at 11:39
  • You have commits that do not contain that file. So, use `xargs --no-run-if-empty`. Affects `blue112's` answer too. Changed my answer. – John_West Mar 18 '16 at 11:47
  • You have only one error_log in certain path, `git filter-branch --index-filter --prune-empty 'git rm --cached relative_path_to_your_file/file'` would be easier. E.g. `git filter-branch --index-filter --prune-empty 'git rm --cached garbage/errors/error_file'` – John_West Mar 18 '16 at 11:49
  • Sorry to be a pain, but now I get: `fatal: ambiguous argument 'find -name "error_log" | xargs --no-run-if-empty git rm --cached --ignore-unmatch': unknown revision or path not in the working tree.` – Brett Mar 18 '16 at 12:51
  • It is this: http://stackoverflow.com/q/21394563 In some shells (and that you're running for your git) `'` does not suite, and one should use double-quote `"`: `git filter-branch --index-filter --prune-empty "find -name error_log | xargs --no-run-if-empty git rm --cached --ignore-unmatch"` I wonder if this would do the trick at last!)) – John_West Mar 18 '16 at 14:04
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/106755/discussion-between-john-west-and-brett). – John_West Mar 18 '16 at 19:07
  • Did you see my message in chat? Sorry, unsure if you get notifications for chat msgs. – Brett Mar 21 '16 at 14:43
0

cd git-project-file

while read i; do git rm --cached $PWD/$i ; done < .gitignore

then make commits

With this you remove those files from present commits.

If you want to remove from the history, you will have to do more. So, comment below if you need to do it.


Explaination:

You said:

I have some files, for example one being error_log and some of these may have accidentally been added to git before they were added to the .gitignore file ...

so what the script does is it reads the .gitignore file line by line so the script runs a while loop where

$i is a line

$PWD is path of present directory

so $PWD/$i is the path of the file/s in each line of .gitignore file.

It run git rm --cached $PWD/$i for each line in .gitignore.

if the file $PWD/$i is not added to git (i.e. if the file in not one of yours error_logs) it does no harm. if it is one of your error_logs, then it removes the file from cache.

make sure you add files to .gitignore first then run the script

Community
  • 1
  • 1
krazedkrish
  • 638
  • 3
  • 10
  • How does this reference the `error_log` file and what does `$PWD/$i` do? – Brett Mar 18 '16 at 12:53
  • I appended the explanation in the above answer, because the comment's presentation is unformatted and not readable. – krazedkrish Mar 18 '16 at 13:33
  • Ahh ok. I guess it's just a bit much through as I know the files I need to delete and the repository is quite large so don't really want to run through and check every file. – Brett Mar 18 '16 at 13:36
  • ok then you can you the find command, if the files are more than than three you can write the file names in a temp.txt file then run while read i; do git rm --cached $i ; done < temp.txt – krazedkrish Mar 18 '16 at 13:40