Mr.
Mr.

Reputation: 10122

Why doesn't .gitignore work across branches?

Working on a local Git (cloned) repository, I have created a branch and placed .gitignore file within it to exclude few directories from git commit. It works just fine, but after switching to a different branch, those directories (the excluded ones) appear in it (on the branch which does not include those directories).

Is it a normal Git behavior? If so, what is the best practice to avoid the issue above?

Upvotes: 4

Views: 1449

Answers (4)

Phillip H. Blanton
Phillip H. Blanton

Reputation: 525

I recently made a bonehead mistake that made me wonder this about .gitignore files. What others have said, the .gitignore file is just like any other file in your repo. I'll answer you inline...


I have created a branch and placed .gitignore file within it to exclude few directories from git commit. It works just fine

All good so far

but after switching to a different branch, those directories (the excluded ones) appear in it (on the branch which does not include those directories).

Yes, switching to a different branch only changes the git repo database that git is looking at. It doesn't change any of the files or directories on your machine. Since the directories are still on your machine's filesystem, they are discovered by git, the local files are compared to the repo data in the branch you are now using, which does not contain the .gittignore file that you set up in the other branch, and git sees them as new, untracked directories / files. It shows them to you as untracked directories / files so that you can decide what to do with them.

This is normal behavior. If you want your .gitignore file to propagate throughout the branches, then it needs to be configured first. Like any other file, it will be applied to any new branch when you create the new branch.

If you want to change the .gitignore file in an ancestor branch and want those changes applied to the descendant .gitignore file(s), then you can either manually edit the .gitignore file(s) in the descendant branch(es) and check it/them in, or merge your branch back with the ancestor branch, then only create new branches from the resulting merged one.

The mistake I recently made was to create a new branch, then before making any changes in the new branch, I realized I needed to make a small .gitignore change back at the parent branch. I switched to the parent branch and made my .gitignore change, moved a couple of files,and checked it all in, then when I switched back to the new branch all of a sudden there were new, untracked files that I thought shouldn't have been there. To fix my mistake, I switched back to the parent branch, deleted the new branch

"git branch -d <branchname>"

and then created another new branch that properly inherited the fresh changes from the parent. It was important to get it right because the files I didn't want to track had local secrets used for development. I couldn't afford the potential of someone inheriting wrong .gitignore settings, and inadvertently checking in files with secrets in them.

I know ^^that's a lot. I hope it isn't too confusing. The gist of it is...

  • When you make a branch, you have an independent copy of the repo that starts as a snapshot in time. Changes made in other branches are not reflected in your new branch, and vice-versa.
  • Switching to a branch, using $git branch <branchname> does not change the files on your local filesystem. It only changes the data that git is tracking. Files that one branch ignores, may be 'tracked', 'untracked', or 'ignored' in other branches.

Upvotes: 0

Christopher
Christopher

Reputation: 44284

There are three other locations you might specify ignored files. From man gitignore (I excluded the CLI one because it's only relevant to plumbing commands):

o   Patterns read from $GIT_DIR/info/exclude.

o   Patterns read from the file specified by the configuration variable core.excludesfile.

If you want to globally ignore files, use the second. Create ~/.gitignore and specify it in your ~/.gitconfig:

git config --global core.excludesfile ~/.gitignore

I would recommend only using this for editor swap files and .DS_Store and the like. Repository-specific ignored files should be specified at the repository level. Also, don't forget to run git rm --cached when you add files to .gitignore that were once tracked.

Upvotes: 2

inigomedina
inigomedina

Reputation: 1831

When you move from branch A to branch B you should have the changes from A already committed in that branch.

Upvotes: 0

Greg Hewgill
Greg Hewgill

Reputation: 993901

The .gitignore file is a file in the repository just like any other. So if you create a new .gitignore file, commit it on one branch, then switch to another, the .gitignore file will disappear. This is normal.

Upvotes: 6

Related Questions