0

Scenario:

(master) git pull origin    //get most up to date remote
(master) git checkout -b mybranch
(mybranch) do some work without committing
(mybranch) git checkout master
(master) git pull origin    //to get updated remote to merge locally
    // pull aborted because I accidentally changed a line in (master)
    // before switching to (mybranch)
(master) git stash   //to disregard the accidental change
(master) git pull origin
    // pull successful
(master) git checkout mybranch
(mybranch) all my uncommited changes are gone???

mybranch now sits at its last commit. There are a few files that were added by git add . that are showing up but there is about 100 lines of code not showing up on the file system.

Is this really what happens when you checkout a different branch without committing? or does git stash stash all uncommited changes regardless of branch? Either way if anyone knows where my progress went I will be eternally grateful.

Update:

This is my normal workflow. I will explain my current understanding of each step. I was not formally taught how to use git with a team, so I would be thrilled to learn a proper workflow. anyway:

(master) git pull origin

I do this to get the most up to date version from github.

(master) git checkout -b mybranch

This creates a new branch that matches master and the online repo.

(mybranch) git add .  //only if I added files
(mybranch) git commit -a

This is me doing all my work. When I get something working correctly, I commit. I repeat this process until I am through working or reach a major checkpoint

(mybranch) git checkout master

switch back to master

(master) git pull origin

if nobody has pushed to the online repo since my first pull, I receive a message saying nothing to pull, otherwise it pulls the updated code to master

(master) git merge mybranch

if there was nothing to pull, this is a FF merge and all is well. If there was an update, here is where I deal with any merge conflicts.

(master) git commit -a

if there were merge conflicts, I make my merge commit. This is only done after all conflicts are handled the code runs without issues

(master) git push -u origin master

update the repository with my code

Like I said I am new to git, so if this workflow is flawed please point it out. Also, if my explanation points to any fundamental misunderstandings, I would appreciate some kind worded educating as well. Gracias to all.

P.S. This is a small group and I prefer to handle all merge commits myself.

thedarklord47
  • 3,183
  • 3
  • 26
  • 55
  • i will update my question, and i'm not offended, I am new to git – thedarklord47 Mar 16 '15 at 04:13
  • also, I had not heard of a work in progress commit. I get that my original post looked like a mess (and it might be), but to me my problems stem from not realizing that uncommited changes are not associated with a branch. – thedarklord47 Mar 16 '15 at 04:40
  • 2
    Pro tip: don't *ever* do any `pull`, `checkout`, and so on, with uncommitted changes. Commit often and early. You can tidy up the commit history later using the `rebase` functionality. – M.M Mar 16 '15 at 05:08
  • yeah that was my issue. I forgot to commit pre-checkout/pull. Thats why I thought the pull failed due to some random char in master, when it was actually just all my uncommitted progress in mybranch. In my normal workflow I do commit often and before any pull/checkout. – thedarklord47 Mar 16 '15 at 05:14
  • And now based on your edit, instead of a crappy comment you get some (hopefully) helpful information. If it doesn't help, let me know and I'll remove it to not add noise to the site. – Roman Mar 17 '15 at 03:23

2 Answers2

5

Short answer: your changes are in the stash. git stash show -p and you'll see them. git stash pop will recover them.

Long answer: uncommitted changes are not associated with a branch. They're just sitting there on the disk. Or, if you added them, in the staging area which is also not associated with a branch. When you switched to master, your uncommitted changes were still there on the disk. When you ran git stash those changes were stashed.

Git will generally protect you and not blow over uncommitted changes. For example, it will not let you checkout a different branch if it would affect a file you have uncommmitted changes to.

$ git st
On branch mybranch
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   blah

no changes added to commit (use "git add" and/or "git commit -a")
$ git checkout master
error: Your local changes to the following files would be overwritten by checkout:
    blah
Please, commit your changes or stash them before you can switch branches.
Aborting
Schwern
  • 153,029
  • 25
  • 195
  • 336
  • This is what I would expect to happen and why I am confused. With uncommited changes, git did not throw the error when checking out master. It is very helpful to know that uncommited changes are not associated with a branch though. This is why I was surprised when (apparently) `git stash` stashed my goodies that i thought were "associated with a different branch" – thedarklord47 Mar 16 '15 at 04:35
  • 1
    p.s. thanks for being nice, showing me how to retrieve my data, seeing my misunderstand, and educating me! Upvoted and selected as answer. – thedarklord47 Mar 16 '15 at 05:02
  • You're quite welcome. Are you still confused? Does something need clarification? – Schwern Mar 16 '15 at 05:04
  • I think my fundamental misunderstanding, thinking that uncommited changes are associated with a branch, was the issue. If you don't mind, could you tell me if there is anything wrong with the workflow I posted in my update? It has been working for me quite well (unless I forget to commit changes as in the original scenario). – thedarklord47 Mar 16 '15 at 05:07
  • 1
    @thedarklord47 It's fine. I merge feature branches with `--no-ff` to preserve the existence of the branch in history so it's obvious the commits are related. – Schwern Mar 16 '15 at 05:20
2

As Schwern said, git will generally try to protect you from losing data. He also gave the correct answer about how to get your work back.

Based on the edit to your question, here are some things you might find helpful to get more out of git.

Think of your work as living in 3 places. In the working directory, in the index (staging) and in the repository. Most git commands you run move data in (or between) one of those three places. This isn't exactly what git does under the hood, it's just a mental model.

add command isn't just for new files, it's generally for moving your work from the working directory into the index (staging area). When you commit, git takes whatever is currently staged and creates a commit out of it. -a you add to the commit command just tells git "don't worry about the index and just go ahead and commit all the changes in all the files".

The staging area is there to allow you to select what will go into a commit and what won't. You don't even have to stage the whole file, git add -p will let you add parts of a file to be committed instead of the whole file. Have debugging statements sprinkled in your code to help you find a bug? Don't want to be part of the commit? No problem, just type n. This allows you to make many small, frequent, commits. On their own small commits aren't very interesting, but when you combine them with git bisect you can quickly narrow down which commit caused a problem. If commit is small (only changed 12 lines for example), you probably already see the problem!

stash isn't associated with any branch, but underneath git just creates a commit to keep track of the changes from the working directory. Because stashes are really commits, even if you accidentally clear the stash you you still haven't lost your work, you can recover it. Stash can help with situations like "oh no, I accidentally started making changes on the wrong branch, I'd like to move them to the right branch." Not a problem, stash, switch branches, unstash. You can also use stash as a quick "did I just break that?" test. You've been editing things and notice something is broken. git stash and your changes are gone. Is it still broken? If yes, it's probably not you. If no, then it's probably you. git stash pop and all of your work is back where it was and you're ready to look what you did to make things stop working.

It's not magic, but once you work with it, it will almost feel like cheating.

Community
  • 1
  • 1
Roman
  • 19,581
  • 6
  • 68
  • 84