0

So a hard crash occurred during a git checkout --merge.

It left the repository in a messed up state - and the uncommitted seems to be gone, although not 100% sure.

In hindsight, perhaps I should have stashed or committed the uncommitted changes first - but then again, whats the point of the that command in the first place (?).

So the question is, if anyone knows what Git does with the uncommitted changes in this case? Are they lost for good or stored in some temporary location? If only they get stored in memory during the process, then I guess it's a lost cause trying to dig them out from somewhere.

Looking at the docs, they doesn't seem to go into details about the process itself https://git-scm.com/docs/git-checkout.

darune
  • 10,480
  • 2
  • 24
  • 62
  • I'm pretty sure the files will be there somewhere. I take it your local repo is in a working state? You could [try this](https://stackoverflow.com/a/91795/542251). It should enable you to find any "dangling" commits – Liam Jun 20 '18 at 12:53
  • It is difficult to reproduce i would guess, since it involves a crash during the checkout with --merge. Question is simpel enough - what does git do to the uncommitted changes during the process ? (and if not lost - a way of recovering would be helpfull) – darune Jun 20 '18 at 13:23
  • @Liam i already tried an "fsck --lost-found" and browsing through the output. Is that different from what you suggest ? – darune Jun 20 '18 at 13:25
  • Honestly, not 100% sure. Give it a go and see what you get. I think it's the same (or at least similar) – Liam Jun 20 '18 at 13:29
  • @Liam that is fair. I do hope someone will provide some insight though - since i do not wan't to spend too much time trying to look for something thats maybe lost for good - which is also the reason for coming here. – darune Jun 20 '18 at 13:33
  • In general GIT is very careful to store everything somewhere. Which is why I presumed it would be a dangling commit somewhere. I'm surprised it's not there TBH. A merge should pull in both branches then merge them. At no point is anything "deleted". What does you commit tree look like and where's the data you missing on that context? – Liam Jun 20 '18 at 13:51
  • @Liam - What "both branches"? The fundamental difference between `checkout --merge` and a normal merge operation like you're describing is that one of the parents is not committed / on a branch at all. Which means that parent (the worktree copy) is going to get clobbered at some point, and a crash during that filesystem operation might corrupt or delete the file. – Mark Adelsberger Jun 20 '18 at 14:22
  • If its any help, the original uncommitted changes spanned a handfull of files (more than 5). – darune Jun 22 '18 at 08:59

1 Answers1

0

I can't answer with 100% certainty as to whether git might stow a backup copy of the work tree; but I can say that I haven't observed it to do so, I find no documentation that says it will do so, and I'd be a little surprised if it went to the cost of doing so. Hopefully someone with code-level knowledge might come up with something more definitive, but as things stand I would say your effort might unfortunately be better directed at confirming whether data was lost from the working file copies and, if so, reproducing the changes from the last committed state.

Not to be a Monday-morning quarterback, but...

I consider any checkout while there are uncommitted changes to be potentially risky; checkout --merge more so because you're explicitly telling git you want it to bypass its normal cautions and merge changes into uncommitted working files. And a crash is a worst-case scenario; an operation that we reason about as though it were atomic may have been interrupted.

Certainly a crash at that particular moment is a fluke, and checkout --merge might save a little time/effort on many, many instances before causing a data loss of this sort.

Still, personally what I like about git is the fact that it gives pretty strong assurances against data loss once something is committed; and commits and branches are "light weight" enough that it's fine to throw around temporary ones. So when I see the few commands that offer me a little savings in exchange for a tiny chance that I might lose data, I choose to avoid it. Doesn't mean that's the only right choice, but if you take a risk then you take a risk.

Mark Adelsberger
  • 42,148
  • 4
  • 35
  • 52
  • The data seems to be lost in the working copy, but im not 100% sure. – darune Jun 21 '18 at 13:35
  • Your answer to my question is mostly speculation. In my experience Git doesn't just hard delete content - checkout --merge should 'update' whatever it can and otherwise create a conflict - which doesn't neccesarily incur an extra cost. I think some facts about the actual process is order here. Does it bulk handle the modifications in memory - and then next override files - then yes, it could well be lost for good. – darune Aug 15 '18 at 09:06
  • 1
    @darune : My answer has some speculation bc your question gives little to go on (which is why noone else has jumped in with a "better" answer). However, you're using that as an excuse to assume that the factual part of the answer is somehow also in question, which it is not. "In [your] experience Git doesn't just hard delete content"? The way the database is managed that's almost true, but in the worktree it's not at all true, both bc some commands tell it to do just that and bc being able to recover from a file rewrite being interrupted is a filesystem issue (and one that most fs's don't do). – Mark Adelsberger Aug 15 '18 at 12:53