user1406626
user1406626

Reputation: 341

Git lists same file modified and not staged for commit?

For some reason Git is telling me I have a file which is both "to be committed" and also "not staged for commit"? This doesn't make sense:

% git status 
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   Dir1/Dir2/filename.cpp
#
# 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:   Dir1/Dir2/filename.cpp

Dir1, Dir2 and filename.cpp are definitely all the same file. I had to add filename.cpp back again to get it to appear as a change to be committed (after it was originally in the repository). About the only thing that may have caused the problem was that I stashed, pull --rebase, then popped the stash? .gitignore does not list Dir1, Dir2 or filename.cpp anywhere and the patterns don't suggest they would catch this file?

Upvotes: 32

Views: 15499

Answers (3)

ams
ams

Reputation: 25559

In CVS, SVN, BZR, and no doubt a dozen other tools, once a file is added that means it'll be included in the next commit.

Not so GIT.

In git you don't "add a file", you "add a change" (sometimes it's called "stage a change").

If you change a file twice you have to "add" it twice.

Upvotes: 12

Cameron Skinner
Cameron Skinner

Reputation: 54276

It means that you made a change to filename.cpp, added that change (with git add), then made another change that has not yet been added.

The "changes to be committed" part means that Git has updated its index with a change. When you run git commit, the changes to the index will be used to create the new commit object.

The "changes not staged" part shows the difference between the index and your working copy.

You can reproduce what you're seeing like so:

  • Edit filename.cpp
  • Run git status. You'll see "changes not staged".
  • Run git add filename.cpp
  • Run git status. You'll see "changes to be committed".
  • Edit filename.cpp again
  • Run git status. You'll see both "changes not staged" and "changes to be committed".

Does that make sense? It's always a little tricky explaining how Git works.

Upvotes: 37

Matthew Farwell
Matthew Farwell

Reputation: 61695

If you modify a file, add it and them remodify the file, you'll get this behaviour. When you do a git add, it adds the changes up to that point, and commiting after that without re-adding only commits the first set of added changes.

$ git status
# On branch master
nothing to commit (working directory clean)

matthewfarwell (master)
$ vi foo.txt <-- add lines 1,2,3 here

matthewfarwell (master)
$ git add foo.txt

matthewfarwell (master)
$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   foo.txt
#

matthewfarwell (master)
$ vi foo.txt <-- add lines 4,5,6, here

matthewfarwell (master)
$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   foo.txt
#
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   foo.txt
#

So if I commit now, only the lines 1,2,3 will be commited.

Upvotes: 5

Related Questions