127

I'm really new to git and I've been trying to understand why git keeps showing whatever I changed in one branch in another branch when I run git checkout to switch between branches First I tried not using git add and didn't work. However, I tried then using git add, but didn't fix the problem. I'm not using git commit yet.

This is basically what I'm doing:

$ git clone <a_repository>  
$ git branch  
* master  
$ git branch testing  
$ git checkout testing  
...edit a file, add a new one, delete...  
$ git status  
    # On branch testing  
    # Changed but not updated:  
    #   (use "git add/rm <file>..." to update what will be committed)  
    #   (use "git checkout -- <file>..." to discard changes in working directory)  
    #  
    #       deleted:    file1.txt  
    #  
    # Untracked files:  
    #   (use "git add <file>..." to include in what will be committed)  
    #  
    #       file2.txt  
no changes added to commit (use "git add" and/or "git commit -a")  
$ git branch  
  master  
* testing  
$ git checkout master  
D       file1.txt  
Switched to branch 'master'  
$ git status  
    # On branch master  
    # Changed but not updated:  
    #   (use "git add/rm <file>..." to update what will be committed)  
    #   (use "git checkout -- <file>..." to discard changes in working directory)  
    #  
    #       deleted:    file1.txt  
    #  
    # Untracked files:  
    #   (use "git add <file>..." to include in what will be committed)  
    #  
    #       file2.txt  
no changes added to commit (use "git add" and/or "git commit -a")  

I thought that, while using branches, whatever you do in one branch, it's invisible to all the other branches. Is not that the reason of creating branches?

I tried using "git add" but the changes are visible in both branches. Do I need to run "git commit" before switching between branches to avoid this?

Mat
  • 202,337
  • 40
  • 393
  • 406
JPZ
  • 1,273
  • 2
  • 9
  • 4

3 Answers3

158

Switching branches carries uncommitted changes with you. Either commit first, run git checkout . to undo them, or run git stash before switching. (You can get your changes back with git stash apply)

Sean Clark Hess
  • 15,859
  • 12
  • 52
  • 100
  • Thank you for replying. I just tried using git stash / git stash apply but the new file is still visible when I switch between branches. – JPZ Apr 03 '11 at 18:14
  • 11
    git stash pop is better unless you want to build up a huge stack of stashes. – siride Apr 03 '11 at 19:00
  • 8
    @JPZ: git stash only deals with tracked files; new files aren't tracked, so they won't get stashed. – siride Apr 03 '11 at 19:00
  • 2
    @JPZ: Should you want to stash away untracked files, the thing to do is `git add` them before stashing. That said, I'm not sure you actually want to stash here - if you intend for those changes to be part of the branch you're switching away from, commit them. (If you intend to switch back to that branch and work on the changes more before committing them, then `stash` may be the right tool for the job.) – Cascabel Apr 03 '11 at 19:22
  • 25
    "Switching branches carries uncommitted changes with you" -- This does make sense and perhaps the worst design idea. What's the point in having branches if you can't work in isolated manner ? !!! – nehem Jan 12 '17 at 23:00
  • 1
    In my case, I have one feature branch from a develop branch. I commited in the feature branch but it shows the changes when I checkout the develop branch as well. – Hitesh Garg Jul 14 '17 at 06:27
  • 1
    You can add the untracked files to your stash by running `git stash -u` This way you will not have the untracked files when you switch to a new branch. – killerkiara Aug 31 '18 at 15:09
  • So unexpected, so unintuitive. The average user clearly expects that switching a branch switches to a completely isolated one by default. Thanks anyway. – Cesar May 11 '21 at 11:11
38

Short answer: yes, you need to commit. Make sure you do it on the right branch, though!

A branch is a pointer to a commit. When you commit with a branch checked out, the branch advances to point to that new commit. When you check out a branch, you're checking out the commit it points to. (You can think of commits as snapshots of your work tree.)

So, if you have changes you haven't committed, they're going to be unaffected by switching branches. Of course, if switching branches is incompatible with your changes, git checkout will simply refuse to do it.

git add is a command for staging changes, which you will then commit. It does not record those changes into the history of the repository. It simply places them into a staging area (the index); git commit then uses the contents of that staging area to create commits.

Cascabel
  • 479,068
  • 72
  • 370
  • 318
1

If anyone arrives here with the same situation as I was in, you are wondering why are you carrying over directories from the branch you switched from even though you had no uncommitted changes, i. e., your working tree (git status) is clean.

Chances are that you are on a Mac and are ignoring the auxiliary files it creates, e. g., the .DS_Store etc. When you switch branches, since Git does not track directories and only files, the directory with the ignored auxiliary files stays since it does not become empty.

Switch to the branch where the persistent directory does not belong and issue tree -a repo_root (make sure you have tree installed). This will show the untracked files causing the directory to persist the branch change.

If you do not care for these files, switch back to the branch where the persistent directory does belong and run something like,

find repo_root -name ".DS_Store" -type f -print -delete

This will recursively delete all the .DS_Store files under repo_root. Run the above command for any other untracked files you do not want or move them out and switch branches.

Et voilà!

scribe
  • 673
  • 2
  • 6
  • 17
  • Alternatively, use `git clean -dfx --dry-run` to see all untracked files. Remove `--dry-run` to delete them. https://git-scm.com/docs/git-clean – Ville May 11 '23 at 11:15