can I checkout into another branch after git add without commiting the changes [duplicate]

I have a homework assignment where I need to make three different implantations to the same program. The professor recommended using git and having each implantation in a different branch. Thing is that when I do a change on a branch named A, it'll also modify the same file in the master branch...I don't want it to carry my changes around every branch, instead keep the changes saved locally on each branch alone. How do i do this ?

(I'm new to using git) (We work on linux, a remote server, on the terminal)

EDIT: The commands i used to make my project directory:

git init

git commit -m "my message"

git checkout // to switch branches

git branch branchname // to create a branch


Solution 1:

When I do:

$ git init
Initialized empty Git repository in MyPath/Test1/.git/

then I create a file test.txt

$ touch test.txt
$ git add test.txt
$ git commit -m " commit 1 "

Now I want to modify it in a different branch

$ git checkout -b branch1
$ echo "Branch 1" >> test.txt

Here it's the tricky part... If I don't add the file using git add test.txt and I don't commit but directly go bak to master:

$ git checkout master
Switched to branch 'master'
M       test.txt

I will see the modifications in master!!:

$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   test.txt

What I should do is to add and commitin branch1:

$ git checkout branch1
$ git add test.txt
$ git commit -m "commit from branch 1"
[branch1 1b562f5] commit from branch 1
 1 file changed, 1 insertion(+)
$ git log
commit 1b562f5be40a50df04f8a2a15b58a7af61742275 (HEAD -> branch1)
Author: xxxxxx<[email protected]>
Date:   Thu Jun 3 16:36:30 2021 +0200

    commit from branch 1

commit 03684e2a02c1a37a8f4546f296c6802686c7a4e9 (master)
Author: xxxx<[email protected]>
Date:   Thu Jun 3 16:31:05 2021 +0200

     commit 1

And if I go back to master and check the log:

$ git checkout master
Switched to branch 'master'

$ git log
commit 03684e2a02c1a37a8f4546f296c6802686c7a4e9 (HEAD -> master)
Author: xxxxx<[email protected]>
Date:   Thu Jun 3 16:31:05 2021 +0200

     commit 1

We won't see the modification ... as expected

SO! what if you want to work on other branches even if you haven't finished with the current branch?

I go back to branch1 and cat its content

$ git checkout branch1
Switched to branch 'branch1'
$ cat test.txt
Branch 1

keep editing

$ echo "Branch 1..1" >> test.txt

Lets add but not commit and try to checkoutmaster

$ git add test.txt
$ git checkout master
error: Your local changes to the following files would be overwritten by checkout:
        test.txt
Please commit your changes or stash them before you switch branches.
Aborting

not posible! you have to commit before, BUT! you don't want a new commit every tima you change branche, so you can just commit --amend

$ git commit --amend
$ git log
commit 40a3a66e2b45a253f9a6ed564e977887c0748bf0 (HEAD -> branch1)
Author: xxxxx<[email protected]>
Date:   Thu Jun 3 16:36:30 2021 +0200

    commit from branch 1 => I can edit the comment!!

commit 03684e2a02c1a37a8f4546f296c6802686c7a4e9 (master)
Author: xxxxx<[email protected]>
Date:   Thu Jun 3 16:31:05 2021 +0200

     commit 1

And now i can safely git checkout master

Solution 2:

The files that you see and edit in your working tree (ordinary files) are not actually in Git. They were copied out of Git when you ran git checkout (or the new git switch; both of these do the same thing for this particular purpose; git switch was added in Git 2.23 as a safer way to do checkouts).

When you run git add and then git commit, you make a new snapshot, archiving all your files in Git. Each commit holds a full snapshot of every file (well, of every file that it holds, but that sounds kind of redundant, doesn't it?). These files are stored inside Git, in a special, read-only, Git-only, compressed and de-duplicated form, as part of each commit.

The de-duplication takes care of the fact that most commits mostly just re-use existing files from some previous commit. It keeps the repository proper smaller than it would be, if the files weren't de-duplicated. But this also means that it's literally impossible to use the files that are stored in Git. So when you run git checkout or git switch, Git will—as you move from one commit to another—remove the old checked out files and replace them with new ones from the new chosen commit.

In order to avoid losing unsaved work, both git checkout and git switch do some safety checking first.1 If you have modified some file, but not committed that modification yet, Git will try to take that modified file with you, into the new branch. This is not always possible, but when it is, you see exactly what you saw:

Switched to branch 'master'
M       test.txt

This M is Git's way of saying: Hey, I noticed that you'd modified test.txt. Rather than just destroying the change you made, I was able to switch branches to master and leave your modified copy of the file in your working tree. I didn't take the copy out of master. If this isn't what you meant to do, you should probably switch back to the other branch, add the file, and commit it.

There is actually a great deal more to this—including when and whether Git can switch branches at all—and a more complete story is in my answer to Checkout another branch when there are uncommitted changes on the current branch. That's an answer to a question about why you sometimes can, and sometimes can't, git checkout another branch without committing your work. It does not address the fact that git checkout is less safe than git switch—the question itself, and my answer, predates the new git switch—and is not about whether any of this is a good idea. It's just about the underlying mechanism.

For now, just remember that the files you see and work on are not in Git. They are in your working tree, for you to see and work on, but as far as Git is concerned, they are just temporary files, for you to play with and for Git to overwrite with git checkout.


1The safety checking in git checkout can be disabled, sometimes without you realizing it. This is why git switch now exists and why it's a good idea to convert to it, but the old git checkout still works. Since you mentioned it in your question, I'm mostly using git checkout in examples here. Also, I've been using Git for about 15 years and have bad habits from the bad old days. :-)