Can GIT track a file only in one branch but not on other?

Issue

I’m using GitFlow as git workflow. And I program for electronic microcontrollers.

While I’m on the development branch I don’t need the compiled HEX file to be tracked or committed, I just need the code. But when I’m on the release or master branch, I do need the generated HEX file to be committed.

At the moment I’m "mentally" ignoring the HEX file, and only stage and commit to it when I need. But its kind of bothering, to have it there, always looking at you, asking "why all the other files, but not me"…
I feel kind of guilty, and I would prefer not to see it there unless I’m on the appropriate branch.

Any suggestion?

Solution

There’s not a great way to do what you want. I’d also suggest you recheck some assumptions, because when you say “…when I’m on [some branch] I do need the generated [anything]…” (emphasis added), that tells me you’re probably not letting your source control system just be a source control system.

The problem with just saying “keep a different .gitignore on each branch” is, (1) it doesn’t account for the fact that you’ll regularly create branches that need to not ignore the HEX file, from a branch that needs to ignore the HEX file; and (2) one of the versions of .gitignore will be seen as a modification of the other, so it’s possible for routine merges to silently carry that change into a branch that shouldn’t get it.

You can use the structure provided by gitflow to make this more manageable, especially if you script the branch-and-merge activities around release branches. You could just keep the HEX file in your .gitignore, but force-add it when staging the first commit on each release branch. A few key points here:

1) All .gitignore does is say that if there are untracked files matching certain path patterns, those files should by default remain untracked. Once a file is tracked, .gitignore has no further effect.

2) As used in point (!), “tracked” just means “in the index”. If a file is in commit A but not in commit B, then moving between commits A and B will generally update the index such that the file becomes tracked or untracked with each checkout, accordingly. But this does give rise to a problem…

2a) If you’re on develop, where the HEX file is .gitignored, but you have an untracked HEX file in your work tree; and then you git checkout master (where master does have a HEX file), git will ignore your untracked HEX file and allow the checkout, causing your local version to be overwritten. You will not be able to recover the HEX file. Again, since you say the file is generated, this may not be a big deal; but it’s something to keep in mind.

3) You can override the default behavior that keeps ignored files untracked by using the -f option of git add, as in

git add -f path/to/HEX/file

And if you follow the gitflow merging patterns, then you could simply do this force-add every time you create a release branch, overriding the ignore rule on release branches (and on master, which is composed of merges from release branches). So far so good.

Of course, those merges to release do present a problem, because every time they will see the new HEX file as conflicting with the old one (since they were created independently as far as git can tell. What you’d want, essentially, is the behavior of the default merge strategy’s “theirs” option (take the version from the branch I’m merging in, if there’s a conflict). You may not want to use that option except for that one file; you could rig something up using .gitattributes maybe.

Also there is a problem if you ever do hotfix branches, because those are branched from master (so they’ll have the HEX file) but you merge them to both master and develop. So each hotfix has the risk of “leaking” the HEX file into the develop branch (after which you’d have to remove it again to get the ignore rule working).

If this seems like a lot of trouble, it is. Again, in my opinion this is because you’re working against the grain of a source control tool. And to clarify, these problems are not peculiar to my proposed solution, but rather will arise with any solution to the problem as stated. If git sees the file popping into existence on each release branch, but not present on develop or feature branches, then merges to master will conflict and hotfixes will risk copying the file to develop, no matter how exactly you got there.

Answered By – Mark Adelsberger

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published