I sometimes use Git from the command-line (with a bit of Googling). That tends to work. I used Tortoise Git in the past for a bit, with good results, although sometimes it was a bit confusing. Now I use Sourcetree, and it happened multiple times that I lost my work. Easiest way: double click a different branch. A bit harder: forget to make a branch up front. And I had it once with rebasing, but I don't do that very often.
I don't know Sourcetree, so I can't comment much on it. I assume "double click" should be a "switch to" (or checkout that branch/commit).
Indeed the most common issue is to switch to a sha, without a branch. (aka detached HEAD) => Been there in my first few weeks, several times. I didn't loose anything, except for a bit of time. But it can feel like things are lost.
Example => If you made a detached commit "forget to make a branch up front"You forgot to create a branch, before switching away. Commits seem lost. But they are not.
Lets say you have
git log --oneline
230d446 (HEAD -> master) C
d802048 B
41345d2 A
git switch -d d802048
HEAD is now at d802048 B
echo 'ABC' > file
git commit -m B1 file
[detached HEAD 8c6336d] B1
1 file changed, 1 insertion(+), 1 deletion(-)
git log --oneline
8c6336d (HEAD) B1
d802048 B
41345d2 A
And now you accidentally
git switch master
Warning: you are leaving 1 commit behind, not connected to
any of your branches:
8c6336d B1
If you want to keep it by creating a new branch, this may be a good time
to do so with:
git branch <new-branch-name> 8c6336d
Switched to branch 'master'
First you will note, that it already gives you all the info you need to recover that commit. (Though that is an improvement of the recent years, and a GUI may not tell you...)
If you do notice immediately you can do
git switch -d -
HEAD is now at 8c6336d B1
You need the "-d" because the target is detached. The single "-" gets you to the previous checkout.
This is the same as "git switch -d HEAD@{1}"
And then there also is
git reflog HEAD
230d446 (HEAD -> master) HEAD@{0}: checkout: moving from 8c6336db21a6e8a9a7e174941697d9265a5696d1 to master
8c6336d HEAD@{1}: commit: B1
d802048 HEAD@{2}: checkout: moving from master to d802048
230d446 (HEAD -> master) HEAD@{3}: commit: C
d802048 HEAD@{4}: commit: B
41345d2 HEAD@{5}: commit (initial): A
And (if you had made several detached commits) you can
git log --oneline 8c6336d
8c6336d B1
d802048 B
41345d2 A
And if you did disable the reflog
(since I do have a reflog, I need to add a param to ignore it)
git fsck --no-reflogs
Checking object directories: 100% (256/256), done.
dangling commit 8c6336db21a6e8a9a7e174941697d9265a5696d1
git log --oneline 8c6336db21a6e8a9a7e174941697d9265a5696d1
8c6336d B1
d802048 B
41345d2 A
There is often much more output, but you do look for "dangling commit"
So your example "double click a different branch" Whatever it does... With the above methods you should be able to get back.
And while - as I said - I don't know Sourcetree, I find it most curious that a double click should have such an effect.
Have you tried "git branch" from the command line, to see if the old branch is still in the list? (or "git reflog", which will show you what HEAD was previously at).
Maybe Sourcetree is hiding it....
"rebasing"Well SVN doesn't have it, so you can't run into issues.
I guess you did not finish the rebase, but also not abort it. And so new commits where made as addition to the rebase. If you then later cancelled the rebase, then the new commits would be "gone" => but not lost.
What actually goes is the temporary branch, on which the rebase was build. But the commits are still there (2 weeks without reflog, 6 weeks with reflog / both configurable).
And it's the same steps as above.
"git status" will tell you if any operation (rebase, bisect, ...) is ongoing.
Here a rebase with a current conflict:
git status
interactive rebase in progress; onto 230d446
Last command done (1 command done):
edit 8c6336d B1
No commands remaining.
You are currently rebasing.
(fix conflicts and then run "git rebase --continue")
(use "git rebase --skip" to skip this patch)
(use "git rebase --abort" to check out the original branch)
Unmerged paths:
(use "git restore --staged <file>..." to unstage)
(use "git add <file>..." to mark resolution)
both modified: file2
Untracked files:
(use "git add <file>..." to include in what will be committed)
file1.txt
no changes added to commit (use "git add" and/or "git commit -a")
It tells you how to abort "git rebase --abort".
And before aborting you can create a new branch. You can stash (or commit (either on the new branch, or detached)) any changes in the worktree.
The biggest risk here is, if you make changes to the worktree (maybe not resolving but making a new feature), if you never commit then, but then use "git rebase --abort" -> because that will ignore the working tree changes and switch to the branch you had been on before the rebase.
So effectively "git rebase --abort" is a way to throw away the current uncommitted worktree.
So if you haven't committed your changes, there are ways to do damage.
But when you do "git rebase --abort" git can't know if changes in the worktree where your attempt to resolve conflicts, and you are giving up, hence no longer needing them...
Or if you 1) forgot that you were still rebasing, 2) added new changes 3) did forget to commit (which you could have, even in a rebase) 4) now realized you were in a rebase....
Btw "git switch -f" will also override a modified worktree.
The -f (force) is like adding an "svn revert".
And well yes, if you are new to git, you don't know any of those commands.
But, you likely have internet. You can ask. Likely find the steps on stackoverflow or similar....
And those steps still work, even if you did further commits. So if you don't have the answer immediately you still haven't lost anything.
(except if you do stuff like "git prune --expire now")