2

I want to ignore a file/directory tree that was previously tracked - ignore it forever but have it not being deleted on a pull - just have it ignored on the repository the pull happened. Is this possible ? Why not (if not) ? How should I proceed ?

NB: the accepted answer in Remove a file from a Git repository without deleting it from the local filesystem - namely git rm --cached path - will result in the file being deleted on a pull. Nasty. Not only that but "it will delete your file if you check out a revision from before the deletion and then check out a revision from after the deletion" (see this comment) See this question for other interesting comments/answers that do not address my issue however.

I am perfectly aware of the --assume-unchanged flag but this is not what I want - I want to tell to git (and all repository clones) "hey, stop tracking this file/tree" but not "delete this file/tree" - so I want to --assume-unchanged globally as it were. If it is not possible (why ?) I need a workaround.

For the record I am trying to bootstrap git to use it to keep/share history and I want to be able to stop tracking files/directories at will - without having them deleted.

Related:

Community
  • 1
  • 1
Mr_and_Mrs_D
  • 32,208
  • 39
  • 178
  • 361
  • I don't have a known answer but I have a feeling this can be solved by adding the file to `.gitignore`. – shadowtalker Aug 04 '14 at 16:40
  • 1
    I'd try `git rm --cached` together with adding the file to `.gitignore`. – che Aug 04 '14 at 16:40
  • As Pavel explained in the question [you linked](http://stackoverflow.com/a/3318849/198244), if this behavior didn't exist then your working directory would accumulate files deleted from the repository. This can lead to other problems, if other processes end up using the files that were supposed to be deleted. Also, it's trivial to restore a local copy of a file that was removed from the repo (also described in Pavel's post). – jamessan Aug 04 '14 at 16:51
  • @jamessan: read that but it's beside the point (who said about _deleted_ files) - the [comment](http://stackoverflow.com/questions/25123374/stop-tracking-a-file-in-git-without-having-it-deleted-either-locally-or-on-pul/25123571?noredirect=1#comment39102558_25123571) by torek in contrary is as always to the point – Mr_and_Mrs_D Aug 04 '14 at 16:55
  • You said about deleted files. That's the entire point of your question -- how to avoid deleting a file from a user's computer when they pull from a git repo where the file has been deleted, so I fail to see how that's beside the point. – jamessan Aug 04 '14 at 16:59
  • To Git, the file is *deleted*. That’s the whole point. Git doesn’t care what other untracked files you have in the working directory; it simply doesn’t even know about them. But it does care about tracked files, and will enforce changes when they are changed (with “deletion” being a possible change). – poke Aug 04 '14 at 17:09
  • @poke: I see - I was hoping that git would be able to simply untrack a file without seeing it as deleted - apparently not the case – Mr_and_Mrs_D Aug 04 '14 at 17:33

2 Answers2

3

I had kind of the same problem, I used git rm --cached <file> and it worked locally but once I made a push to the remote server it deleted also the files, and I did not want that.Then I found git update-index --assume-unchanged <file> and it ignores the local changes and does not delete it from the remote server, worked like a charm!

Luis Mata B.
  • 312
  • 3
  • 8
1

This is not possible. To prevent new changes from being tracked, you need to remove the file from the repository (using git rm or git rm --cached). This adds a change to the commit that removes the file. When that change is then applied in other repositories, the remove action is performed, resulting in the file being removed.

poke
  • 369,085
  • 72
  • 557
  • 602
  • This sounds like an oversight in git - or am I mistaken ? – Mr_and_Mrs_D Aug 04 '14 at 16:46
  • Not really. Otherwise you couldn’t ever remove files from the repository when checking out commits. – poke Aug 04 '14 at 16:48
  • 1
    It's not so much "oversight" as "completely outside the design constraints". Suppose for instance path `p` is in the first commit with contents `1`, in the 2nd with contents `2`, and in the third it's marked "ignore this now, leave it alone". If you check out rev 1 first, then rev 3, then rev 2, what goes in file `p`? What if you check out 2, then 1, then 3? What if you check out 3, then 1, then 2? – torek Aug 04 '14 at 16:49
  • thanks @torek - the idea is that in all 3 scenarios rev 2 will be checked out finally (rev 2 and 3 have the same contents) - indeed though if one keeps editing this file the contents will be overriden... Anyway - the idea is that it is natural to be able to tell the SCM 'hey - stop tracking this file/tree" - not just locally. So my only workaround is to `filter-branch` ? – Mr_and_Mrs_D Aug 04 '14 at 17:01
  • But if you download the repo, check out rev 2 first and then rev 1, the file contents will be `1`. If you then switch to rev 3 and the file contents become `2`, that would not be obeying the instructions in rev 3, which say "leave it alone"! As for `filter-branch`, that *copies* commits to new, different commits. In the new, different commits you can remove the file and create a `.gitignore` to keep git from noticing the file. Then you can extract some version of it, and it's now untracked. – torek Aug 04 '14 at 17:06
  • *“rev 2 and 3 have the same contents”* – no, in 3, the file doesn’t exist. As for your possible workarounds, I’m still not sure what you actually want to accomplish. Rewriting the whole history is likely not a good idea. If you just want to be able to set up some files easily, why don’t you include a script that does that or a template file (e.g. `configuration.example.ini` instead of `configuration.ini`)? – poke Aug 04 '14 at 17:07
  • @torek: the (non existent) instructions at 3 would not say "leave this alone" - would rather say "this is tha latest version known to Us, and we won't be bothering to track changes anymore". Instead git says - "this poor file I used to track is now deleted, what a shame" - and hurries to propagate the news on `pull`. Dunno – Mr_and_Mrs_D Aug 04 '14 at 17:37
  • @poke: "no, in 3, the file doesn’t exist" - we were discussing the hypothetical case of being able to just "untrack" a file as opposed to deleting it. My use case: think dropbox "previous versions" and "selective sync". So I would filter branch and add to gitignore then pull - once I pulled the modified history the file would be "untracked" and it wouldn't be deleted - right ? (btw I am fully aware of what rewriting history means - as well as tricks to have a local file not versioned etc) – Mr_and_Mrs_D Aug 04 '14 at 17:41
  • Well no, if you rewrite the whole history to never know about the file, the repository then checking out that rewritten history will still switch from a state where the file existed to a state where it doesn’t. So it will still remove the file. – poke Aug 04 '14 at 18:17
  • @poke: I would hope that rewriting history while having the file ignored from the first (rewritten) commit would leave it alone wouldn't it ? – Mr_and_Mrs_D Aug 06 '14 at 13:33
  • Yes, but a working directory will always have a commit checked out, and if that commit includes the file and the newly checked out doesn’t, the file will still be removed. E.g. you’re on commit `A` which knows the file. Then you rewrite the whole history so the file was never in the repository, ending up with commit `A'`. A repository that has `A` checked out will now need to update, checking out `A'`. And that process will remove the file. – poke Aug 06 '14 at 13:46