threads / bug / 37366

Bug: partially staged file is committed in whole, if there is another staged file

Subject: Bug: partially staged file is committed in whole, if there is another staged file

## tl;dr

2 messages between Aug 17, 2014 and Aug 17, 2014.

replies: 1people: 2as markdown or json

Paul Beckingham· Aug 17, 2014, 17:05 UTC · lore
If I have two modified files, and file1 is staged (git add file1), and file2 is partially staged (git add -p file2), and then try to commit only the partially staged file2, git commits *all* changes to file2, not just the staged part.
There is no bug without file1 also being staged.
Here is a transcript illustrating the problem:

$ uname -v Darwin Kernel Version 14.0.0: Tue Jul 29 16:22:25 PDT 2014; root:xnu-2782.1.62~4/RELEASE_X86_64

$ git version git version 2.1.0

$ git status -sb
## master
M  file1
MM file2
$ git commit file2 -m "adding patch"
[master 066a6e2] adding patch
 1 file changed, 2 insertions(+)

$ git status -sb ## master M file1 $

Regards, Paul

Junio C Hamano· Aug 17, 2014, 19:03 UTC · re: Paul Beckingham · lore

Re: Bug: partially staged file is committed in whole, if there is another staged file

Paul Beckingham <paul@beckingham.net> writes:
Show 12 quoted lines
> $ git status -sb
> ## master
> M  file1
> MM file2
> $ git commit file2 -m "adding patch"
> [master 066a6e2] adding patch
>  1 file changed, 2 insertions(+)
>
> $ git status -sb
> ## master
> M  file1
> $
You would likely to have seen
    $ git diff --name-only HEAD^ HEAD
    file2

This is a very deliberate design decision, and the command is working as expected. Here is why.

The filenames (technically, they are not filenames but pathspecs, i.e. can be patterns to match the filenames) on the command line of "git commit" are used to first "git add" them internally to form the tree used for the next commit, and are not used to limit the paths with changes that are already in the index.

I am not opposed to adding a new mode to use pathspecs to limit the paths to be committed from the index without consulting the working tree at all, but unless this is explicitly done as a new mode, you would end up forcing people to say

    $ edit file3 file4
    $ git add file3
    $ git commit file3

while all existing users have been expecting that after modifying a file "file3" and commit the changes to that file (and to no other files), they can say

    $ edit file3 file4
    $ git commit file3
without the extra step of adding it.

We could however add a check to detect the case where your pathspec matches a path that has changes both in the index and in the working tree, and error it out. To those who never use "git add", there is no change to the path in the index and the check will not trigger. To those who do "git add file3" the path and then not modify the working tree before running "git commit file3", there is no change to the path in the working tree relative to the index and the check will not trigger.

Such a change may still bite the people who often start working incrementally with repeated "edit file2 && git add -p file2" and then when they are satisfied with the full contents of file2 run "git commit file2" without an extra "git add file2" to add the last remaining change in the working tree to the index, though, and we would need to let people override the check with "--force" or something to work this extra check around if we were to do so; I do not offhand know if it is worth it.

Thanks.

← back to recent threads