I have a project, but some of the files are big, in /data/guilds/*
, which I don't commit.
How can I git pull in a way that will get all the recent code, but not delete files that don't exist? /data/guilds
doesn't exist in the actual source, so shouldn't be affected when it is pulled.
When I tried to git pull, I got this:
error: Your local changes to the following files would be overwritten by merge:
data/guilds/500785463624335390.json
data/guilds/611278159555461180.json
data/guilds/684492926528651336.json
data/guilds/753312192165838938.json
data/stats.json
You might not commit those files, but someone did. They are in some commits. In particular, they exist in the commit you asked Git to merge.
If you want to avoid using them, start by avoiding git pull
, because that means run git fetch
, then run a second Git command. The second command is up to you, but must generally be one of git merge
or git rebase
. If you do not make a choice on your own—either explicitly or by setting up your own default—the default that Git will use is to run git merge
.
The git merge
command uses three commits:
In this case, what has happened is that someone—whoever made the commit you're asking Git to merge—has added these files as new files since that common starting point. You haven't added them to your commits, but they have added them to theirs.
For Git to combine your current committed state—which lacks those files; they're just there in the way in your working tree, not in your current commit—with their work requires that Git create those files from scratch, containing the data that are present in the commit you've told Git to merge. If Git were to do that, this would wipe out those untracked files, replacing them with tracked files from the commit you're asking Git to merge.
You could follow Git's advice (which you snipped here) to either commit those files or move them out of the way, but that's probably not the right thing to do. Unfortunately for you, there is no single right thing to do. You may have to do several wrong things, as it were. 😀
Again, the root of the problem here is that someone has committed these files. No part of any existing commit can ever be changed: not by you, not by the other person involved, not by Git itself. So if you don't want to use those files, you cannot use those commits, at least not directly.
The good news is this: you do not have to use those commits. Simply make some other commits that are better than those commits. Use these new-and-improved commits instead.
The bad news is that to make these new and improved commits, you'll need another place to work, or you'll need to move your current data files out of the way, because you cannot work directly on a commit. All commits are stored in a special, read-only, Git-only format that is useless for doing any actual work. For this reason, Git does not have you work directly on commits. Instead, Git extracts commits out into a working tree, where you have files, instead of commits. You can use files. Files let you get work done. (Commits don't.) So you can take this other commit, made by someone else, that has these files, and extract all these files into a working tree.
If you extract these files into your own main working tree, this will, obviously, destroy your current files. So either save them somewhere outside your current (main) working tree, or do this work somewhere outside your own main working tree:
You can do the work in a new clone, which—being a separate clone—will have its own working tree, its own branches, its own origin
, and so on.
Or, you can use git worktree add
to add a new working tree that is on a new branch. This is a little more complicated in some ways, and a little simpler in other ways.
In any case, once you have an area in which to work, you can start with their commit, fix it up so that it lacks the data files that it should lack, make a new commit from that set of files, and now you have a new commit added to their branch that is suitable for use with git merge
, so that you can merge that commit to your branch.
Note that this does not fix their own error. Their commit, which contains these files, still exists. You'll need them, whoever they are, to pick up this new change that omits these data files. When they do pick that up, this change will remove their data files! They will need to restore them—perhaps from a commit that has them—and start working the way you do, with these as untracked files that they do not add and commit.
To make sure they don't add-and-commit these data files again in the future, once they have fixed their mistake, they (and you) can use a .gitignore
file. This won't fix any of the old commits! The old commits cannot be fixed. No part of any existing commit can ever be changed. You and they can simply avoid using the old commits.