4

I'm a newbie to git, and got a little ahead of myself in creating/deleting branches and wanted to figure out the right process. Basically, I started on a new branch (branch_a) and then made a few changes. I then decided to test a third party package knowing it may not work as I wanted. At this point, I have a few changes in branch A which I didn't stage or commit. I went on to checkout a new branch (branch_b). I played around with this "test branch" and then decided to delete it. First I did a check-out of the original branch:

git checkout branch_a

Then, I deleted the branch thinking all the changes I made would get deleted too:

git branch -d branch_b

So the branch gets deleted but when I go back to branch_a to continue work from where I left off, I see the changes I made in branch_b are still there. Since I didn't commit anything before, I can't figure out how to separate the changes pre-branch_b and post-branch-b. Is this still possible?

And in terms of "the process", is there a better way to create and delete test branches? E.g. should I have used git reset --hard?

stoneage
  • 510
  • 3
  • 14
  • 1
    Are you sure you didn't stash or commit your changes to `branch_a`? Usually git doesn't allow you to check out a branch while your working directory is dirty. If you really didn't stash or commit you're out of luck and will have to revert the `branch_b` changes by hand, git has no way of knowing what you want to keep. – dtech Jan 25 '14 at 21:22
  • Nah, didn't stash or commit any changes. The new checkout worked fine just giving me this message: `M db/schema.rb` `M log/development.log` `Switched to a new branch 'branch_b'` Looks like I should have used git stash! – stoneage Jan 25 '14 at 21:31
  • Yes, or just commit. With git/distributed version control you generally want to commit often. You can always squash your commits/branch afterwards or organize everything neatly when merging back to master with [`git merge --squash branchname`](http://stackoverflow.com/questions/5308816/how-to-use-git-merge-squash) – dtech Jan 25 '14 at 21:42
  • 1
    @dtech git allows you to change branch even with dirty working tree, for example if the new branch point to the same commit as the old one. – michas Jan 25 '14 at 22:01
  • @user2301903 Please add the output of `git branch -vv` to your question. – michas Jan 25 '14 at 23:13

2 Answers2

4

I'm going to conjecture at what happened.

You made changes in branch_a. You did not commit. You checked out new branch branch_b, did some stuff, did not commit. Now you switched back to branch_a. git will indeed let you carry over a dirty working directory.

To Clean It Up (assuming my conjecture is right)

In order to clean up your mess, perform a git status. You need to git add all the items you want to for branch_a. Then perform a git commit to save what you want in branch_a. Note that it only commits the items you added to the stage.

Now you're free to go back to branch_b, git add stuff you want there, and commit that, too. git status has nice help text to help you along the way.

My recommended workflow:

You work on branch_a. You get an idea to try something different. If you think you'll be back to branch_a within 15 minutes, perform a git stash save <message>. This keeps the branch_a stuff separate. If you're going to be longer, just commit it. Don't worry, you can clean it up later with an interactive rebase: git rebase -i. Stashes are a bit annoying to have hang around, and you can accidentally delete them or pop them when you don't mean to.

Now go back to master, and create branch_b. My favorite way is the all-in-one command git checkout -b branch_b. Now you can work there. Once you're done experimenting, again either stash or commit. Remember as long as you don't push, you can commit willy nilly and clean it up later with interactive rebasing.

Check out branch_a and continue working there. If you had stashed something, pop the stash: git stash pop. Otherwise you committed, and it's already there waiting for you.

Mike Monkiewicz
  • 4,481
  • 1
  • 22
  • 19
  • Yea, that's basically what I did but I also deleted `branch_b` thinking it would discard changes made in that branch. I fixed it by hand since it wasn't too convoluted. Next time, I'll utilize `git stash` and also commit more often (rather than after hitting a "milestone") – stoneage Jan 26 '14 at 15:07
1

Use gitk --all to see which branch currently points to which commit.

If you did not commit your changes, git does not know anything about your change.

Use git status to check if the files in your working tree differ from those known to git. It will also tell you how to change that.

Before changing branch make sure you either commit your changes (to let you current branch know about your changes) or discard you changes. Never change you branch with uncommitted changes.

It will also help to configure a good git prompt for your shell. For bash you can use something like:

PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[31m\]$(__git_ps1)\[\033[00m\]\$ '
GIT_PS1_SHOWDIRTYSTATE=yes # show changed files as `*`
GIT_PS1_SHOWUNTRACKEDFILES=yes # show new files as `%`
GIT_PS1_SHOWSTASHSTATE=yes 
GIT_PS1_SHOWUPSTREAM=auto

If you set you prompt that way, just make sure it does not show * or % before changing branch. And if it does use git status for help what to do.

michas
  • 25,361
  • 15
  • 76
  • 121