5

I am trying to reproduce a problem that resulted from my attempted answer to this question.

In short

A github user tried to do git pull --rebase and that user's local files were deleted. I have tried to recreate this scenario on github but in my case nothing is deleted.

So how can I reproduce the scenario where git pull is destructive?

The details

Part 1:

  • A user asked how to synchronize local changes to a newly-created remote repository.
  • git push failed because the user did not have remote changes (as expected).
  • I suggested to use git pull --rebase, then resolve, then git push again.
  • But my suggestion resulted in the user's local files being deleted. (see original question)
  • note that the files were tracked (committed locally), so the user was able to restore them.

Part 2:

  • I created a repo called https: //github.com/user/myrepo, initialized with README and .gitignore
  • locally, I did:

    initialized repo locally

    > mkdir myrepo
    > cd myrepo
    
    > echo AAAAA > fileA.txt
    > echo BBBBB > fileB.txt
    > echo ignoreme > .gitignore
    
    > git init
    

    committed the files locally

    > git add .
    > git commit -m"initial commit"
    

    tried to pull remote changes

    > git remote add origin https://github.com/user/myrepo.git
    > git branch --set-upstream-to=origin/master master
    
    > git pull --rebase
    
  • the result was (as expected):

    First, rewinding head to replay your work on top of it...
    Applying: initial commit
    Using index info to reconstruct a base tree...
    Falling back to patching base and 3-way merge...
    Auto-merging .gitignore
    CONFLICT (add/add): Merge conflict in .gitignore
    error: Failed to merge in the changes.
    Patch failed at 0001 initial commit
    The copy of the patch that failed is found in: .git/rebase-apply/patch
    
    When you have resolved this problem, run "git rebase --continue".
    If you prefer to skip this patch, run "git rebase --skip" instead.
    To check out the original branch and stop rebasing, run "git rebase --abort".
    
  • At this point, if I do ls, my local files are still on my filesystem.

    > ls -a
    .          ..         .git       .gitignore README.md  fileA.txt  fileB.txt
    

Update:

Here is a comment from the original user who had the problem.

from user7342807:

... I installed wordpress this morning and did exactly this.

git init
git add .
git commit -m "initial commit"

at this point, I had realized I already created the github page for it, WITH a default readme in it.

So, not knowing this would be an issue, I tried to push as

git remote add origin http://github.com/user/repo.git
git push -u origin master

This is when I received the message:

$ git push -u origin master
To https://github.com/user/project.com
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'https://github.com/user/project.com'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

So, instead of force pushing and erasing that README file on github, I did git pull --rebase and git showed me this message

First, rewinding head to replay your work on top of it...

I waited about 5 minutes, before I ctrl+C out of the process, and realized there were about 8-9 files removed from the wordpress site. git status also showed me the removed files.

I was able to recover those files using git reflog which showed me my first commit on HEAD@1 and I recovered my files with git reset --hard "HEAD@{5}"


What could have caused the files to be deleted from the other user's local filesystem?

Please note that there is a similar question that asks how to un-delete files when this happens. So this case occurs and people are losing their files.

martin jakubik
  • 4,168
  • 5
  • 29
  • 42
  • Did the incident delete *untracked* files? I ask because there are multiple merge strategies available to git, and since you're now sitting in the middle of a merge conflict, if git decided that the best way to handle the conflict is to try to merge the other way around, it might've simply checked out the changeset from the remote locally, and tried to merge onto that. This way it would look like the files are deleted but in reality you are still sitting in the middle of a merge conflict. Also, rebase replays changesets one at a time, which might explain this. – Lasse V. Karlsen Mar 06 '17 at 12:27
  • These are tracked files. They have been committed. I will update the question. – martin jakubik Mar 06 '17 at 12:37
  • @LasseV.Karlsen it would be interesting to create a file that might cause git to use this reverse merge strategy... I see your point about rebase replay as well, but in this case I believe there was only a single commit resulting from a git init with README + .gitignore on the github repo. – martin jakubik Mar 06 '17 at 12:51
  • If git checks out a different changeset it never deleted any files at all, they're still present in the commit history. Yes, it can and will remove them from your working directory, but not from the commits. However, if moving the HEAD or branch references around is interrupted you might end up with local commits that are unreachable other than through the reflog. – Lasse V. Karlsen Mar 06 '17 at 12:54
  • Not really an answer, but: (1) generic standard advice: avoid `git pull` (2) You're merging unrelated histories, which in the latest Git requires `--allow-unrelated-histories` when using `git merge`; (3) we'd need to know precisely how the upstream repository was created (GitHub allows you to create empty or non-empty) *and* your local Git version; (4) it may be a Windows-Git-specific bug. – torek Mar 06 '17 at 19:32
  • @torek, I was going to suggest you expand on your answer a bit, but it looks like [you've already done that](http://stackoverflow.com/a/34503589/203797) :) – martin jakubik Mar 07 '17 at 08:05

1 Answers1

0

git pull will delete ever tracked file on another path.

refer to Why git rm --cached not remove local ever tracked file but others

LF00
  • 27,015
  • 29
  • 156
  • 295