2

General Question: How can one use Git locally alone (i.e. by oneself) in such a way that merging changes from a new branch into master, or moving from branch to branch using checkout, doesn't delete everything in the new branch and the master branch?

Or if one wants to avoid git deleting everything and leaving no backups, is it essentially necessary to be working with a remote repository (e.g. GitHub), not just a local one?

Specific Case:
I had two branches for my local git repository, master and equality, located in the folder .../ps/ps3. I was in the branch equality and I wanted to merge my changes into master.

So first I did git merge and this returned the error:

fatal: No remote for the current branch.

So then I figured that I needed to be in master rather than equality to merge my changes from equality into master. So what I did next was: git checkout master. This produced the following error:

error: Your local changes to the following files would be overwritten by checkout: ps3/ps3.aux ps3/ps3.log ps3/ps3.pdf ps3/ps3.synctex.gz ps3/ps3.tex Please commit your changes or stash them before you switch branches. Aborting

I interpreted that error as follows: nothing happened, I am still in the equality branch, I should make another commit of equality branch if I want my changes in equality to be saved when I use them to rewrite the master branch, rather than git rewriting from an earlier version of equality.

My terminal prompt indicated that I was still in the directory .../ps/ps3 and in the branch equality, so I didn't think that anything was wrong. When I did git commit -am "Finished correct proof" I didn't get an error message.

5 files changed, 155 insertions(+), 29 deletions(-) rewrite ps3/ps3.pdf (72%)

Now it was either this command, or the one immediately following it, which deleted everything, not just equality and every commit in that branch, but also master and every commit in the branch, and even the entire folder .../ps/ps3 of the repository.

I did git merge (I was still in the branch equality) and I got the error message:

fatal: No remote for the current branch.

This confused me, because why would I need a remote of anything to do anything? And what did it have to do with my current situation? I guessed it was just an arcane way of complaining that merging the changes from equality into master needed to be done from master.

So next I did git checkout master and got no error, just Switched to branch 'master'. In spite of not getting any errors, I still think this may have been the step that deleted everything, since after doing this my terminal no longer showed that I was in either equality or master, so it seemingly must have at the very least deleted the entire repository, i.e. all of the files in it and the containing folder.

My terminal still said I was in a directory named ps3 even though it didn't also list a git branch like it should have. So next I did git merge and then git merge equality but both returned the error:

fatal: Unable to read current working directory: No such file or directory

Then I did ls, there was no output, then I did cd .. and ls -a and the directory ps3 was not listed as being a subdirectory of ps. I.e. the containing folder for the repository, as well everything and every branch in it had been deleted somehow. I didn't even know it was possible to do this with Git -- I thought that the worst possible thing that could happen if I screwed up was that the earlier version in the master branch would overwrite the newer version in the equality branch, and that I could then just do git revert multiple times to get back the equality branch. And I thought git checkout just moved between branches, rather than deleting everything.

This page makes it seem like git checkout master does what I expected it to do, namely switch to the master branch, rather than deleting everything. Also this page makes it seem like git checkout should help restore files, so why did it delete all of mine?

Chill2Macht
  • 1,182
  • 3
  • 12
  • 22

1 Answers1

2

First, syntax: you're right that git merge needs to be run on the destination branch (and then you have to give it the name of the branch you want to bring in).

What happened: you were in a subdirectory of your working copy when you ran the git checkout master, and it removed that subdirectory because master didn't have any files there. (The "unable to read current working directory" is what happens when you remove a directory while a shell is inside it.)

The good news: nothing is lost. You're just still in the repository, rather than outside it looking at the space it once occupied. Now is the time to run git merge equality and you'll see ps3 come back.

The bad news: you committed your generated files (.aux, .log, etc.). Don't do that; maybe you should go back to equality and git commit --amend them out of existence before you merge. (It's a lot harder to fix nicely after you merge.)

Davis Herring
  • 36,443
  • 4
  • 48
  • 76
  • Holy **** I want to marry you right now. This is amazing – Chill2Macht Sep 21 '17 at 16:30
  • To exclude the generated files, that would be putting `**/*.aux`, `**/*.log`, etc. in a .gitignore file in the root directory of the repository? – Chill2Macht Sep 24 '17 at 01:06
  • 1
    Yes; you can leave out the `**/` when it's at the beginning. That only affects new `add`s, though. Removing them from your **current** commit (that you haven't **merged** yet!) is `git rm ps3/ps3.aux ...` and then the `--amend` I mentioned. – Davis Herring Sep 24 '17 at 01:26