34

I create a new branch

git checkout -b mybranch

then I delete a file from it

git rm --cached myfile.txt

but I want to keep it in the master; why when I checkout to the master

git checkout master

I get an "error: The following untracked working tree files would be overwritten by checkout: file.txt" and if I force the checkout

git checkout master -f

the file is deleted from the file system?

I am sure I am missing something, but I just wanted to remove the file from a branch and not from the master while it seems that git wants to merge the branch when I checkout master.

The reason why I used git rm and not gitignore was that the file was already been committed.

Eugenio
  • 3,195
  • 5
  • 33
  • 49

3 Answers3

27

If you want to keep tracking myfile.txt on master but deleted from mybranch, then you simply need to delete it and commit the delete.

git checkout -b mybranch
rm myfile.txt
git commit -am "delete myfile.txt"

Now when you checkout master, you'll see your file returned and when you checkout mybranch it will be gone again.

Note that if you merge mybranch into master, it will be deleted on master then too.

Jeff Puckett
  • 37,464
  • 17
  • 118
  • 167
  • 2
    Thanks, it works but I needed to add a "git add -u" before committing or use "git rm" instead of rm. If you edit your answer I'll accept it. – Eugenio May 30 '16 at 20:19
  • 1
    @Eugenio thanks for catching that! I edited my answer to use `git commit -am` which will add all changes, including removed files. – Jeff Puckett Jun 03 '16 at 11:59
  • 2
    I can't believe this ans got 8 votes ... I think ques is ... if there is a way to restrict a file to master and not to other branches ... for example secret info can be kept in a property file in master branch and master branch will be accessible by admin only – Nitin Jha May 02 '20 at 05:51
6

git will see the file as untracked because it is not committed yet. You have to commit the change before you switch branches.

So you created a branch and made changes to that branch. When you try to switch back to master git will disallow this, because there are changes that are not committed yet (or explicitly ignored; (that is actually what the untracked means)

The reason the file is restored when you force checkout (git checkout -f master) master is because the file is in master

If you want to do this you will have to do the following

Create and check out branch

git checkout -b somebranch

Remove the file from somebranch (--cached will actually remove the file from the index, but will leave the file intact on your filesystem. See git-rm reference docs)

git rm --cached somefile

Commit the change

git commit -m "Remove somefile"

This will remove the file from git, but not from disk, so now to git you have an untracked change (somefile is on disk but not in git)

If you want other contributors to be able to checkout the branch, link it to a remote

git push --set-upstream origin somebranch

Now the file is removed from origin/somebranch and not master

When you add a file to .gitignore it is not removed from the repo if it is already committed. Changes to the file, howeve, will be ignored (so also deleting it). If you do that you still have to remove the file and commit. After that git will not track the file anymore when recreated (or any other action on the file).

Rik
  • 3,647
  • 2
  • 25
  • 34
  • This is exactly what I did, I commited before "checkout master". Files were not restored (which was what I expected, actually they were still in the filesystem before checking out), they have been DELETED from the filesystem after the checkout. – Eugenio May 24 '16 at 19:52
  • Don't use --cached. Just do 'git rm somefile' this will delete the file from your file system too. It should be restored when you checkout master again – Rik May 24 '16 at 19:53
  • 'git rm somefile' will actually do the same as 'git rm --cached somefile && rm somefile'. So only removing it from the index (cache) and leaving it on your file system is to git as if you added the file on disk but not to git). Hope clears somethings up – Rik May 24 '16 at 20:04
  • thanks for the comment; what is the purpose of --cached then? – Eugenio May 24 '16 at 21:39
  • In case you want to remove something from git but not from disk. 'rm somefile' will do the opposite. – Rik May 24 '16 at 23:20
  • yes so that is exactly what I wanted, removing the file from git (in that branch) but not from the disk, why was it wrong? – Eugenio May 25 '16 at 07:18
  • It is not wrong, but if you remove it from disk and not from git, but the file is in the git working tree and not ignored git will see it as a change. – Rik May 25 '16 at 07:25
  • sorry I still don't get it, you said "If you remove from the disk and not from git" but I did the opposite – Eugenio May 25 '16 at 07:35
  • Sorry, my mistake, it is indeed "If you remove it from git, not from disk" – Rik May 25 '16 at 07:36
  • so there is no way to delete from git (but keep it in the filesystem) and then checkout to master? – Eugenio May 25 '16 at 09:04
  • If you mean you want to maintain the file, because it has changed compared to master, then you can remove the file from git using `--cached`. After that commit the change. Then stash your local changes using `git stash`, checkout to master and apply the stash with `git stash pop` – Rik May 25 '16 at 09:09
  • it has not changed, it's just that I don't want the file in a branch (in git, but preserving it in the file system) but I want to keep it in the master (both in git and in the file system). – Eugenio May 25 '16 at 09:37
  • Then you should ignore the file in your branch. That will prevent git from tracking the file. – Rik May 25 '16 at 09:39
  • as I said, I couldn't ignore it because was previously committed – Eugenio May 25 '16 at 09:41
  • What exactly do you mean by "I can't ignore the file"? If you do the following (assuming you have `somefile` in master 1. `git checkout -b somebranch` 2. `git rm --cached somefile` 3. echo "somefile" >> .gitignore 4. `git add .gitignore` 5. `git commit -m "Remove somefile and stop tracking changes"` 6. `git push --set-upstream origin somebranch` This will create the branch, remove the file from git index and stop tracking the file in `somebranch` but still have the file on disk – Rik May 25 '16 at 09:47
  • However, doing a hard clean (`git clean -fdx`) or switching to `master` and then back to `somebranch` will remove the file from disk (because it is not tracked in `somebranch` anymore. – Rik May 25 '16 at 09:51
  • What I meant is it was already committed (see here http://stackoverflow.com/questions/6535362/gitignore-after-commit) – Eugenio May 25 '16 at 14:09
  • ✅ This is the answer that worked for my case. Thanks @Rik – Jean Manzo Apr 28 '21 at 15:16
0

Commit the change on mybranch before swapping back to master.

Charles Durham
  • 2,445
  • 16
  • 17