0

Here is my scenario. I was on branch A, where I made some changes to certain file on my local working copy.

/launcher/file.esb

I basically want the following:

  1. Ignore the changes made to this file completely. I accomplished this using assume-unchanged
  2. Untrack this file from version control, which I tried to accomplish using .gitignore.

  3. Preserve the changes to this file on my local working folder as I checkout different branches. A->Develop->B->C etc...

It is #3 that I am not able to accomplish. As soon as I checkout a new branch and do a pull, the old changes are overwritten on the file.

Why is this happening? Shouldnt inclusion of this file path into .gitignore effectively take out this file completely out of reach of the version control tentacles?

How can I achieve #3?

This question is unlike the one mentioned in the "possible duplicate" link. Heres why:

Here's basically what I want in lay words. "Put this one particular file of mine in essentially a 'shell', that neither gets overwritten during ANY git operations nor gets taken into account if changed". Its basically excluding any form of version control synchronization between that file and staging/remote. This local file and the version on staging/remote must exist with mutual and total disconnection.

Ace
  • 1,501
  • 4
  • 30
  • 49
  • Possible duplicate of [Stop tracking and ignore changes to a file in Git](http://stackoverflow.com/questions/936249/stop-tracking-and-ignore-changes-to-a-file-in-git) – Paul Hicks Nov 01 '16 at 21:43

2 Answers2

4

This is happening because the file is already part of the repository. So when you switch branches you get the version of this file from the branch you are checking out. The gitignore file only prevents git from seeing files that are not a part of the repository. This is done, so git doesn't include certain files in commands like git add . or git commit -a. And assume-unchanged option tricks git into not seeing the changes, but that means that Git feels free to overwrite the file on checkouts, since it knows the file to be no different from the committed version.

If what you want is to remove this file from git control and manage the changes to it yourself, you can use git rm --cached /launcher/file.esb and commit the change. This will remove this file from the index and the file will no longer be tracked by git. The --cached option prevents git from actually removing the file from your working directory. You might have to do this separately for each branch though, since removing file from one branch doesn't remove it from other branches. To do this you might want to undo assume-unchanged and then use git stash command to temporarily stash your local changes.

Mad Wombat
  • 14,490
  • 14
  • 73
  • 109
  • git rm --cached, I have tried it out like million times. The problem is that when I commit the git rm'd file and push the branch to origin, that file shows up as "deleted" during PR. When I try to merge that branch of mine with development, will that file be actually removed from Dev? Either case I am in trouble as that file shows up as removed during PR. – Ace Nov 03 '16 at 18:26
  • Here's basically what I want in lay words. "Put this one particular file of mine in essentially a 'shell', that neither gets overwritten during ANY git operations nor gets taken into account if changed". Its basically excluding any form of version control synchronization between that file and staging/remote. This local file and the version on staging/remote must exist with mutual and total disconnection. – Ace Nov 03 '16 at 18:33
  • As far as I know, there is no standard way of doing what you want. When you do `git pull` you essentially merge your remote repo into your local (`git pull` is basically a shortcut for `git fetch` and `git merge`). So if a file is controlled by the remote, it will be merged into local on a pull. The simple solution is to do `git stash` before you do `git pull` and do `git stash pop` after the pull, so your local changes stay around. That should work fine as long as the file doesn't get changed by someone else in a fashion that might cause a conflict – Mad Wombat Nov 03 '16 at 19:41
  • Another way would be to try and use git hooks to move your version of the file out of the way before the pull and restore it after, but I have never used hooks, so I don't know. – Mad Wombat Nov 03 '16 at 19:43
  • Personally, I have made a shell alias for somewhat similar reasons (a bit different, I just want my local changes to stick around without commiting) `alias pull='git stash && git pull --rebase && git stash pop'` you might want to be careful and inspect the output carefully to make sure the pop worked properly and didn't fail because of conflicts. – Mad Wombat Nov 03 '16 at 19:46
  • Same goes for switching branches, doing stash, checkout then stash pop should preserve your local changes without affecting anything else – Mad Wombat Nov 03 '16 at 19:48
1

Untrack this file from version control, which I tried to accomplish using .gitignore.

You tried and you failed. .gitignore is read only when you update the index, i.e. you prepare the next commit. If a file was already committed, adding it to .gitignore doesn't help telling Git to stop tracking the file.

You have to also remove the from the index (using git rm --cached) and commit the change. Only then Git stops tracking the file. Adding its name to .gitignore only tells it to stop listing it in the Untracked files section on the output of git status.

However, if you checkout a commit that was created before you removed the file from the repo, the commit contains the file and Git will try to check it out too.

axiac
  • 68,258
  • 9
  • 99
  • 134