FredrikNoren / ungit

The easiest way to use git. On any platform. Anywhere.
MIT License
10.43k stars 636 forks source link

My local repo is broken, possibly because of ungit #1176

Open tengwar opened 5 years ago

tengwar commented 5 years ago

I'm not sure how to report this bug as nothing was printed to the terminal and I couldn't find any sort of Ungit log on the disk.

Today I used NPM to update ungit from 1.4.35 to 1.4.36. I was on Windows 10, Git version is 2.20.1.windows.1, node v11.0.0, npm 6.4.1, I ran ungit in Firefox 64.0.2. I used ungit for a while, pulled from the upstream, created a branch (in terminal or in ungit, I'm not sure), made some commits and wanted to push them. It turned out this branch was tracking upstream/master instead of origin/branch. I was afraid I pushed some commits earlier (that would be bad since they would land in upstream/master as I had the permissions to push there). I wanted to see the current state of upstream/master. In ungit I clicked to fetch upstream and then origin in a quick succession (browser was lagging a bit). Suddenly ungit told me that the list of changed files was too long and could slow down the browser. I ran git status in terminal and a wall of text started appearing, listing all the files in the repository. I wasn't sure what happened so I manually edited .git/config to set the branch's upstream to origin/branch and ran git fetch upstream followed by git fetch origin. It didn't help of course. I listed the branches and it seems the local branch list got overwritten with the list of branches from upstream. I couldn't even run git reflog because it said that my current branch had no commits yet (because it didn't exist anymore). git reflog --all shows things like this:

80e41ec6f (origin/BoostChronoToStdChrono, BoostChronoToStdChrono) refs/remotes/origin/BoostChronoToStdChrono@{0}: fetch origin: storing head
c26732636 (origin/generators, generators) refs/remotes/origin/generators@{0}: fetch origin: storing head
[and few more entries that are as above but for other branches; if branch had a counterpart in upstream, it's listed next to the remote branch as it's now a local branch]
8bc5e2c67 (tag: [here goes a long list of tags], origin/legacy, legacy) refs/remotes/origin/legacy@{0}: fetch origin: storing head
151324f84 (origin/load-whole-files-into-mem) refs/remotes/origin/load-whole-files-into-mem@{0}: fetch origin: storing head
f9912f58f (tag: [XXX], origin/master, origin/HEAD, master) refs/remotes/origin/master@{0}: fetch origin: storing head
[and few more entries that are as above but for other branches]
f9912f58f (tag: [XXX], origin/master, origin/HEAD, master) refs/heads/master@{0}: fetch upstream: fast-forward
82422b2fc refs/heads/master@{1}: reset: moving to 82422b2fc0221f1a54cef1483e3fd54f19479feb
ace9360d4 refs/heads/master@{2}: commit: [commit message here; that was a commit from today but not the newest one as I made few commits after it]
7c6ec3b54 refs/heads/master@{3}: commit: [commit message here; that was an even earlier commit from today]
[And then some other work and some other pulls but after about 30 lines it ends at the clone operation even though I was working in this repo for way over a month already.]

I'm not sure what happened exactly but I lost a day of work. Of the commits I made today only 2 appear in the reflog. Was it my fault or ungit's? Is there any ungit log somewhere on the disk? Is there any more info I should add to the bug?

jung-kim commented 5 years ago

Can you share how you have configured your repo?

  1. Are you working off of master branch? (which I would discourage)
  2. If yes, fetch operation will move remote master branch tag to the newest one in the fetch
  3. If you could provide ungit's console log it would be helpful.
  4. I would encourage making commits frequently with or without ungit as you could go back to it.

I'm bit unclear on what or how this happened, but fetch operation should not move local branch tag as it appears to happened here.

can you also share what the git config looked like for both remote and origin during the incident?

tengwar commented 5 years ago
  1. No, I was working on a feature branch which was branched from master. To be precise I made a new feature branch from master and was cherry-picking commits from a WIP/dirty feature branch, splitting and cleaning up come commits in the process.
  2. Yes, I know the remote branch pointer will get updated.
  3. 
    ## Ungit started ##

Took 2291ms to start server. Navigate to http://localhost:8448/#/repository?path=[path to my repo] Terminate batch job (Y/N)? y

4. I made several commits. I could have tried to push them earlier though.

Git config looked like this:

[core] repositoryformatversion = 0 filemode = false bare = false logallrefupdates = true symlinks = false ignorecase = true [remote "origin"] url = [origin repo url here] fetch = +refs/heads/:refs/remotes/origin/ [branch "master"] remote = origin merge = refs/heads/master [remote "upstream"] url = [upstream repo url here] fetch = +refs/:refs/ [user] email = [my email here] [gui] wmstate = normal geometry = 1109x563+86+162 300 255 [branch "the-one-i-was-cherry-picking-from"] remote = origin merge = refs/heads/the-one-i-was-cherry-picking-from [branch "the-one-i-was-committing-to"] remote = origin merge = refs/heads/the-one-i-was-committing-to


From what I remember before I manually edited the config (as described in the report) the last part looked like this:

[branch "the-one-i-was-committing-to"] remote = upstream merge = refs/heads/master



And it reminded me one thing: when I created the branch the-one-i-was-committing-to I forgot to checkout it, so the current branch was still master. I made a few commits and saw that they ended up in my local master instead of the-one-i-was-committing-to. To fix it, I used ungit to move the-one-i-was-committing-to to where the master was at that time (newest commit I made), then moved master to where the origin/master was (and upstream/master too but it was not shown in ungit). I think that was the cause of the-one-i-was-committing-to having a wrong remote branch being set as a push target. It could also be related to the borked fetch.

EDIT: I managed to find and recover my commits using `git fsck --lost-found` and then running `git show` on the resulting commit hashes until I found my last commit from yesterday. So they were still there, just not in the reflog.
jung-kim commented 5 years ago

I'm glad to hear that you have found your work!

Is there anything ungit can do that could have prevented this? Having more clear target remote repo is definitely on my todo but I'm little short on how I can do that with my limited UI experiences.

p.s. I will add gist fsck --last-found within readme for "when things go kaboom and how to recover" for the people who might run into similar situation.

tengwar commented 5 years ago

Is there anything ungit can do that could have prevented this?

I think moving a branch caused it to have a wrong remote branch set as the push target. If you can reproduce it, it would be nice to fix it. (Details are in my previous comment.) Alternatively letting user see which remote branch is set for a local branch would help too.

And the issue with my branches being overwritten... IDK if it's Git's or Ungit's fault and there are no logs left so I guess it's impossible to reproduce it. :/