6

I have some new files that I didn't add to git yet; I'm not sure I will, I'm still undecided. But I want to get whatever is latest in the server.

However, when I do a git pull I get the error error: Your local changes to 'XXXX' would be overwritten by merge. Aborting., where XXXX is my new file.

How can I tell git to download the changes and new files from the server, tell me about possible conflicts between what's on the server and my local modifications to files already in the repository, while at the same time not aborting because I have new files locally?

I don't want to add them to .gitignore, as I have this situation frequently and I don't want to be adding and removing files from .gitignore all the time for silly stuff... especially because I don't want to run the risk of forgetting about a certain file that in the end I would decide that it has to be added to the repository, so I want git status to keep telling me about them. Sometimes I run git status -uno when I want to ignore new files, and then sometimes I run git status to see what's new and decide what to keep and what to discard. But I couldn't find an equivalent option for git pull.

My attempts at googling take me to people who want to overwrite their local changes with what's on the repository, or other similar scenarios. :( After reading the documentation I found that I can do a git fetch to bring my local repository up to date, that didn't yield any errors, but it also didn't bring the changes to my working copy. I can't figure out the next step after that. :-/ In any case, a pull with no errors would be ideal...

msb
  • 3,899
  • 3
  • 31
  • 38
  • Commit your changes, then pull, then `git reset origin/master` to undo your local commits (but leave the files in your working directory). This is a very safe and easy approach. – Dietrich Epp Apr 18 '18 at 17:58
  • This can cause merge conflicts and may not be something OP wants. – Ru Chern Chong Apr 18 '18 at 18:00
  • mm... the suggestion is to temporarily commit everything just to be able to pull, then reset things to what they were before? yeah, doesn't seem like something I want. If I understand this correctly, I would lose any uncommitted changes I made to the code. – msb Apr 18 '18 at 18:02
  • Possible duplicate of [How do I resolve git saying "Commit your changes or stash them before you can merge"?](https://stackoverflow.com/questions/15745045/how-do-i-resolve-git-saying-commit-your-changes-or-stash-them-before-you-can-me) – phd Apr 18 '18 at 18:08
  • It's not a duplicate because the core of my issue is not losing files that are not part of the (local or remote) repository, which is something that is not even mentioned in the other question. I don't know how I could edit my post to make this clearer, since it's in the title and the first paragraph. – msb Apr 18 '18 at 18:43
  • Maybe interesting: https://stackoverflow.com/a/26549583 – djvg Jan 16 '19 at 10:25

2 Answers2

7

You will have to either stash it first and apply the changes after you have pulled from the remote or reset the current branch to the last commit. Resetting the branch will cause you to lose your changes.

git stash

// after you have pulled from remote
git stash apply 
// OR
git stash pop

A very good explanation on the difference between apply and pop can be found here


You can also choose to reset your current branch with the following command.

git reset --hard
Ru Chern Chong
  • 3,692
  • 13
  • 33
  • 43
  • reset means I'd lose the local files and changes, doesn't it? If I stash, how do I merge the stashed stuff with the pulled stuff? – msb Apr 18 '18 at 17:57
  • Have you even looked at the link? – pishpish Apr 18 '18 at 17:58
  • 4
    There was no link when I asked. :P – msb Apr 18 '18 at 17:59
  • Yes. Reset will lose the local changes. After pulling, you can use `apply` or `pop` to bring back the local changes. You can do whatever you want as per normal. – Ru Chern Chong Apr 18 '18 at 17:59
  • 1
    Let me see if I get this. First I stash, which means I'm saving my code changes plus the new files in some temporary place. Then I pull, and I won't get any errors. Then I pop the stash, which will restore my code changes and new files back into my working copy, on top of the latest pulled code. Is it? – msb Apr 18 '18 at 18:04
  • Hi @msb, finally do you think git stash is a simple and working procedure for ignoring untracked when pulling ? I face the same issue, thank you. – Rémy Hosseinkhan Boucher Jun 10 '20 at 11:59
  • 1
    @RémyHosseinkhanBoucher that was 2 years ago, but if I remember correctly, it worked. You can make a backup of your changes before doing all that, if you don't want to take risks, and after you try you'll know. ;) I haven't needed it ever since then. lol :/ – msb Jun 10 '20 at 17:23
  • For my future reference, unstashing worked fine for new untracked samples; however, for files with local changes, the unstashing process tried to merge and when there was a conflict it made a mess, keeping both versions with markers to which is the repository and which is local. I have yet to find out how to keep only the local version, so that I can do a `git diff` and see the differences between local and repository... – msb Sep 22 '21 at 23:33
6

As you probably know, git pull is basically git fetch followed by git merge.

The step that is failing is not the git fetch, it's the git merge:

... overwritten by merge

Note the last word here is merge. What this means is that your undecided-ness:

I have some new files that I didn't add to git yet; I'm not sure I will, I'm still undecided.

has already been decided for you, by someone else, at least for one such file: that particular file is added now, in that other commit. That's the one that Git will overwrite.

You now have a choice of various options:

  • Don't merge (or don't merge yet): you can leave the file untracked. I think this is pretty clear, but it leaves the situation unresolved. Eventually you'll (probably?) have to merge....

  • Do merge: the file will become tracked. You then have sub-choices about how Git should deal with your existing untracked file:

    • Add and commit. Git will merge your change-since-the-base with their change-since-the-base. Presumably both changes are add this file, i.e., the file is not in the merge base. This means the conflict will be an add/add conflict, which is kind of a pain.
    • Save your version of the file elsewhere, removing the untracked one. Let Git merge (as fast-forward or real merge, whichever it does). Manually merge in your own changes, add, and make your own new commit.
    • The other guy is wrong, and the file should not be tracked: Save your version of the file elsewhere. Let Git merge. Remove the file and commit, committing the removal. You can then put your own untracked file back.

There are some additional options (such as rebasing instead of merging) but they all wind up with the same situation: either the file is tracked (as it is in the commit you told Git to merge), or you must update to that commit anyway, remove the file, and commit again to make a commit in which the file won't be tracked.

The way you "save the file elsewhere" is up to you: for instance, you can just move it out of the work-tree entirely, or you can use git stash to make a commit that has the file.

When it works, git stash is pretty convenient, but because it actually makes two or three commits that are not on any branch, it is quite a complicated little beast, and when it goes wrong it becomes very difficult to deal with. So for anything that itself might be complicated, I like to avoid git stash. Note that git stash by default stashes only tracked files, so you must git add it to get it into the two commits that git stash normally makes. You can use git stash -u to specifically make a third commit that holds the untracked files, but this makes the stash harder to deal with.

torek
  • 448,244
  • 59
  • 642
  • 775
  • "has already been decided (...) by someone else (...): that particular file is added now, in that other commit" - but there's no other commit and no someone else. :-/ – msb Apr 18 '18 at 21:45
  • I do admit this is an odd error. I could swear I had new files around before and didn't get this error. But when I check the server, it's not there. Unless it was there in the past and got deleted (which should have been long ago) and now git is confused? idk.... :/ – msb Apr 18 '18 at 21:46
  • There's definitely another commit, otherwise there would be nothing to merge. Whoever made that other commit is the "someone else", even if that's you. :-) – torek Apr 18 '18 at 21:59
  • omg..... you're right! Well, sort of. There was no other commit. :$ But I `git add`ed a file half a year ago and never committed. Everything that was being reported as "new" in `git status` was getting on the way. I `git reset` that one file, committed the other new stuff, and now `git pull` works! You were wrong that there was another commit disturbing things, but you were right that there was another pending operation. Thanks! – msb Apr 18 '18 at 22:10
  • Hm, now that the pull's merge is done, try `git ls-files --stage` (note that this will generate a LOT of output, one line per tracked file). If you had `git add`ed the file at any point, that copied it into the index/staging-area, and it's been in every commit you made since then except for any commits you made by first taking it back out of the index/staging-area. Remember that every commit is a complete snapshot of *every* file: use `git ls-tree -r ` to see them all, for instance. (If you `git commit ` you get a temporary index/staging-area; I assume you are not doing that.) – torek Apr 18 '18 at 22:21
  • no, I always commit specific files, I never do a generic commit to everything, so what's new stays new until I specifically commit it. From what you're saying, I guess I'm full of temporary index/staging-areas? I'm still assimilating this whole process. lol – msb Apr 18 '18 at 22:32
  • Aha, that's an unusual work-pattern. Using `git commit ` is the same as `git commit --only `: copy the *current commit* to a new index / staging area, `git add` those specific files to that staging area, commit using that staging area, then update the normal index / staging area from the successful commit and remove the temporary one. That would keep the file tracked (if you added it once) but never actually commit it, which would explain this. – torek Apr 18 '18 at 22:34
  • Unusual for whom? lol ;) been doing this my whole life... and so do my team-mates. Especially because we have multiple people fiddling around the same work copy. :$ ¯\\_(ツ)_/¯ don't judge us, believe me, this is already a big improvement over the previous process... lol – msb Apr 18 '18 at 22:38
  • Thanks @torek for the tip about -u for untracked files :-) – Kieran Ryan Feb 16 '22 at 18:06