threads / discuss / 3645

seperate commits for objects already updated in index?

Subject: seperate commits for objects already updated in index?

## tl;dr

11 messages between Mar 14, 2006 and Mar 15, 2006.

replies: 10people: 4as markdown or json

Paul Jakma· Mar 14, 2006, 16:37 UTC · lore
Hi,

Dumb question, imagine you made changes to a few files, and ran update-index at various stages in between:

$ git status # # Updated but not checked in: # (will commit) # # modified: foo/ChangeLog # modified: foo/whatever # modified: bar/ChangeLog # modified: bar/other

The changes in bar/ are unrelated to the changes in foo/ - how do you commit each seperately? Git doesn't seem to want to let me:

   $ git commit -o bar
   Different in index and the last commit:
   M       bar/ChangeLog
   M       bar/other
   You might have meant to say 'git commit -i paths...', perhaps?
git commit on its own wants to commit all the above files.
what's the silly thing I've missed?
Thanks.
regards,
-- 
Paul Jakma	paul@clubi.ie	paul@jakma.org	Key ID: 64A2FF6A
Fortune:
Never tell a lie unless it is absolutely convenient.
Linus Torvalds· Mar 14, 2006, 17:00 UTC · re: Paul Jakma · lore

Re: seperate commits for objects already updated in index?

On Tue, 14 Mar 2006, Paul Jakma wrote:
Show 27 quoted lines
> Hi,
> 
> Dumb question, imagine you made changes to a few files, and ran update-index
> at various stages in between:
> 
> $ git status
> #
> # Updated but not checked in:
> #   (will commit)
> #
> #       modified: foo/ChangeLog
> #       modified: foo/whatever
> #       modified: bar/ChangeLog
> #       modified: bar/other
> 
> The changes in bar/ are unrelated to the changes in foo/ - how do you commit
> each seperately? Git doesn't seem to want to let me:
> 
>   $ git commit -o bar
>   Different in index and the last commit:
>   M       bar/ChangeLog
>   M       bar/other
>   You might have meant to say 'git commit -i paths...', perhaps?
> 
> git commit on its own wants to commit all the above files.
> 
> what's the silly thing I've missed?

You've already marked them all modified in the index (using git-update-index), so git commit thinks you are confused by naming them again and saying "only".

The simplest thing to do is to do
	git reset

to reset your index back to your HEAD (but obviously DON'T use the "-f" flag, which will also force the working tree!). That will make your index clean, and undo the fact that you've already marked things to be committed with "git-update-index".

Then you can just do
	git commit -o bar

and everything should be fine, because then git doesn't think you're doing something insane.

		Linus
Paul Jakma· Mar 14, 2006, 17:04 UTC · re: Linus Torvalds · lore

Re: seperate commits for objects already updated in index?

On Tue, 14 Mar 2006, Linus Torvalds wrote:
Show 6 quoted lines
> The simplest thing to do is to do
>
> 	git reset
>
> to reset your index back to your HEAD (but obviously DON'T use the "-f"
> flag, which will also force the working tree!).
Ah, of course! (I knew I was being dumb ;) ).
Show 6 quoted lines
> Then you can just do
>
> 	git commit -o bar
>
> and everything should be fine, because then git doesn't think you're doing
> something insane.
Yep, thank you!
regards,
-- 
Paul Jakma	paul@clubi.ie	paul@jakma.org	Key ID: 64A2FF6A
Fortune:
The less a statesman amounts to, the more he loves the flag.
 		-- Kin Hubbard
Linus Torvalds· Mar 14, 2006, 17:20 UTC · re: Paul Jakma · lore

Re: seperate commits for objects already updated in index?

On Tue, 14 Mar 2006, Paul Jakma wrote:
Show 10 quoted lines
> On Tue, 14 Mar 2006, Linus Torvalds wrote:
> 
> > The simplest thing to do is to do
> > 
> > 	git reset
> > 
> > to reset your index back to your HEAD (but obviously DON'T use the "-f"
> > flag, which will also force the working tree!).
> 
> Ah, of course! (I knew I was being dumb ;) ).

Well, I actually think git is being somewhat of an ass, for no really good reason. It's true that you are doing something pretty strange by _both_ using "git-update-index" and "git commit -o" but the fact is, at least when adding files, that would be expected (ie you have to mark a file in the index to add it).

I also think that test is historical, from before Junio cleaned up how "git commit" worked - it _used_ to be that "git commit" would work in the current index, but these days it generates a new index to commit when you do "-o", so there's really no _technical_ reason to refuse the partial commit any more as far as I can see.

So I don't know. I don't think you were being dumb, I think git could have been friendlier to you.

		Linus
Paul Jakma· Mar 14, 2006, 17:27 UTC · re: Linus Torvalds · lore

Re: seperate commits for objects already updated in index?

On Tue, 14 Mar 2006, Linus Torvalds wrote:
Show 5 quoted lines
> Well, I actually think git is being somewhat of an ass, for no 
> really good reason. It's true that you are doing something pretty 
> strange by _both_ using "git-update-index" and "git commit -o" but 
> the fact is, at least when adding files, that would be expected (ie 
> you have to mark a file in the index to add it).

Well, I tend to work on one thing, then notice something else unrelated (or in a support file), fix/tweak that, etc.. I use the index for 'way-point' diffs, rather than commit things I havn't quite tested yet (or dont know whether they'll be useful yet).

Show 5 quoted lines
> I also think that test is historical, from before Junio cleaned up 
> how "git commit" worked - it _used_ to be that "git commit" would 
> work in the current index, but these days it generates a new index 
> to commit when you do "-o", so there's really no _technical_ reason 
> to refuse the partial commit any more as far as I can see.
Aha. So that check possibly could just be removed?
> So I don't know. I don't think you were being dumb, I think git 
> could have been friendlier to you.
:)
git reset works just fine too.
regards,
-- 
Paul Jakma	paul@clubi.ie	paul@jakma.org	Key ID: 64A2FF6A
Fortune:
A day for firm decisions!!!!!  Or is it?
Junio C Hamano· Mar 14, 2006, 23:51 UTC · re: Linus Torvalds · lore

Re: seperate commits for objects already updated in index?

Linus Torvalds <torvalds@osdl.org> writes:
Show 8 quoted lines
> I also think that test is historical, from before Junio cleaned up how 
> "git commit" worked - it _used_ to be that "git commit" would work in the 
> current index, but these days it generates a new index to commit when you 
> do "-o", so there's really no _technical_ reason to refuse the partial 
> commit any more as far as I can see.
>
> So I don't know. I don't think you were being dumb, I think git could have 
> been friendlier to you.

I have to go back to the list archive, but if I recall correctly the refusal was added to be friendlier -- by being safer -- and was not there in the earlier round of -o/-i proposal.

Junio C Hamano· Mar 15, 2006, 03:24 UTC · re: Junio C Hamano · lore

Re: seperate commits for objects already updated in index?

The background behind this is around beginning of February 2006, the thread "Two ideas" by Carl Worth. And the current behaviour is defined by this commit. I'll talk about a possible improvement but first, here is what it does:

commit 130fcca63fe8e7e087e7419907e018cbbaf434a3
Author: Junio C Hamano <junkio@cox.net>
Date:   Sun Feb 5 00:07:44 2006 -0800
     ...
     - "git commit paths..." acquires a new semantics.  This is an
       incompatible change that needs user training, which I am
       still a bit reluctant to swallow, but enough people seem to
       have complained that it is confusing to them.  It
    
       1. refuses to run if $GIT_DIR/MERGE_HEAD exists, and reminds
          trained git users that the traditional semantics now needs
          -i flag.
    
       2. refuses to run if named paths... are different in HEAD and
          the index (ditto about reminding).  Added paths are OK.
    
       3. reads HEAD commit into a temporary index file.
    
       4. updates named paths... from the working tree in this
          temporary index.
    
       5. does the same updates of the paths... from the working
          tree to the real index.
    
       6. makes a commit using the temporary index that has the
          current HEAD as the parent, and updates the HEAD with this
          new commit.
    ...
The check that prevents you from doing
	$ edit A B
	$ git update-index A B
        $ git commit -o B

is the rule #2, which I think could use further improvement. It is to address the "committing skewed files" issue Carl brought up in that thread.

It might be better to further check if the working tree file is the same as the index, and to allow a commit in such a case.

The intent of rule #2 is to prevent this from happening:
	$ edit A B
        $ git update-index A B
        $ edit B again
        $ git commit -o B

When this happens, the real index will have _old_ contents of B that never was committed, and does not match what is in the index. But after the commit, we will match the real index to what was committed, so we will _lose_ the index entry for B before the second edit you explicitly told git to remember by saying 'update-index'.

On the other hand, in your original sequence:
	$ edit A B
        $ git update-index A B
        $ git commit -o B

B being committed would be different between HEAD and index, but that is what we are going to commit anyway, so after this commit, B will be in sync with the updated HEAD.

To put it in another way, "commit -o" is a short-hand for people who do not want to run update-index themselves (IOW, people who just want to use git without worrying about the index file). If you use update-index to mark "this is what I want to commit" yourself, you should do so consistently. If you are not ready to commit A but you want to commit B, do not mark both of them and expect "commit -o" to do magic fixups.

Paul Jakma· Mar 15, 2006, 13:28 UTC · re: Junio C Hamano · lore

Re: seperate commits for objects already updated in index?

On Tue, 14 Mar 2006, Junio C Hamano wrote:
<snip - interesting, thanks>
> It might be better to further check if the working tree file is the 
> same as the index, and to allow a commit in such a case.
That would be a nice improvement.
Show 6 quoted lines
> The intent of rule #2 is to prevent this from happening:
>
> 	$ edit A B
>        $ git update-index A B
>        $ edit B again
>        $ git commit -o B
Show 6 quoted lines
> When this happens, the real index will have _old_ contents of B 
> that never was committed, and does not match what is in the index. 
> But after the commit, we will match the real index to what was 
> committed, so we will _lose_ the index entry for B before the 
> second edit you explicitly told git to remember by saying 
> 'update-index'.

That would indeed be annoying, and I'd obviously prefer to have to run 'git reset' than have the above happen!

However, I'd have expected that any porcelain command would synchronise index with HEAD after a commit. See below for my (still newbie-ish ;) ) user-level mental model of git.

Show 9 quoted lines
> On the other hand, in your original sequence:
>
> 	$ edit A B
>        $ git update-index A B
>        $ git commit -o B
>
> B being committed would be different between HEAD and index, but 
> that is what we are going to commit anyway, so after this commit, B 
> will be in sync with the updated HEAD.

Right. So if the file in the index and working tree are the same (hey, i just ran update-index after all), then that check could be loosened. The only thing the commit can do is bring the /3rd/ piece of the puzzle (HEAD) in sync :).

Show 7 quoted lines
> To put it in another way, "commit -o" is a short-hand for people 
> who do not want to run update-index themselves (IOW, people who 
> just want to use git without worrying about the index file).  If 
> you use update-index to mark "this is what I want to commit" 
> yourself, you should do so consistently.  If you are not ready to 
> commit A but you want to commit B, do not mark both of them and 
> expect "commit -o" to do magic fixups.

I guess my problem here is that I consider the index to be a 'weak' cache.

I like to use it for intermediate way-points or "weak commits", however if I commit to HEAD I /really/ want what (I consider to be) the two /strong/ sources of file information (HEAD and working file) to be synchronised, and the 'weak' cache updated then to match.

I wasn't expecting the 'weak' cache of the index to prevent me synchronising my 'strong' sources (HEAD and working file). I was expecting the 'weak' cache to be updated to the 'strong' ones.

If I want to synchronise this 'weak' cache, I'll do so explicitely (though, there isn't a user-obvious distinction in commands for this, there's no obvious "git-commit-index"). Maybe part of the problem here is that git-commit tries to hide the index/working-tree/HEAD distinction? I don't know.

Anyway, if git-commit can lift "Rule 2" where file in working tree and index match, that'd be great - but I can easily live with git-reset till then. ;)

Thanks for the informative email!
regards,
-- 
Paul Jakma	paul@clubi.ie	paul@jakma.org	Key ID: 64A2FF6A
Fortune:
A violent man will die a violent death.
 		-- Lao Tsu
Andreas Ericsson· Mar 15, 2006, 14:00 UTC · re: Junio C Hamano · lore

Re: seperate commits for objects already updated in index?

Junio C Hamano wrote:
Show 41 quoted lines
> The background behind this is around beginning of February 2006,
> the thread "Two ideas" by Carl Worth.  And the current behaviour
> is defined by this commit.  I'll talk about a possible
> improvement but first, here is what it does:
> 
> commit 130fcca63fe8e7e087e7419907e018cbbaf434a3
> Author: Junio C Hamano <junkio@cox.net>
> Date:   Sun Feb 5 00:07:44 2006 -0800
> 
>     
>        2. refuses to run if named paths... are different in HEAD and
>           the index (ditto about reminding).  Added paths are OK.
>     
> 
> The check that prevents you from doing
> 
> 	$ edit A B
> 	$ git update-index A B
>         $ git commit -o B
> 
> is the rule #2, which I think could use further improvement.  It
> is to address the "committing skewed files" issue Carl brought
> up in that thread.
> 
> It might be better to further check if the working tree file is
> the same as the index, and to allow a commit in such a case.
> 
> The intent of rule #2 is to prevent this from happening:
> 
> 	$ edit A B
>         $ git update-index A B
>         $ edit B again
>         $ git commit -o B
> 
> When this happens, the real index will have _old_ contents of B
> that never was committed, and does not match what is in the
> index.  But after the commit, we will match the real index to
> what was committed, so we will _lose_ the index entry for B
> before the second edit you explicitly told git to remember by
> saying 'update-index'.
> 

Can't this be done by updating .git/index first and then use the temporary index to commit? Then .git/index would match the current tree and everybody would be happy with very little tweaking. Doing the temporary index commit first could cause data-loss as described above if the updating of .git/index somehow fails and the user is unaware of it (or what to do to fix it).

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se
Tel: +46 8-230225                  Fax: +46 8-230231
Junio C Hamano· Mar 15, 2006, 19:25 UTC · re: Andreas Ericsson · lore

Re: seperate commits for objects already updated in index?

Andreas Ericsson <ae@op5.se> writes:
Show 6 quoted lines
> Can't this be done by updating .git/index first and then use the
> temporary index to commit? Then .git/index would match the current
> tree and everybody would be happy with very little tweaking. Doing the
> temporary index commit first could cause data-loss as described above
> if the updating of .git/index somehow fails and the user is unaware of
> it (or what to do to fix it).

You have to think about how to rewind it when the user decides later not to commit by for example giving an empty commit message or killing the editor. The order of things need to be to populate the index to be committed so that we can give preview in the commit log template upon 'commit -v', spawn the editor and get the final version of log, and then make a commit. So it may or may not be doable -- I haven't thought about it through, and currently have not much incentive nor inclination to think about it myself right now.

Andreas Ericsson· Mar 15, 2006, 19:43 UTC · re: Junio C Hamano · lore

Re: seperate commits for objects already updated in index?

Junio C Hamano wrote:
Show 21 quoted lines
> Andreas Ericsson <ae@op5.se> writes:
> 
> 
>>Can't this be done by updating .git/index first and then use the
>>temporary index to commit? Then .git/index would match the current
>>tree and everybody would be happy with very little tweaking. Doing the
>>temporary index commit first could cause data-loss as described above
>>if the updating of .git/index somehow fails and the user is unaware of
>>it (or what to do to fix it).
> 
> 
> You have to think about how to rewind it when the user decides
> later not to commit by for example giving an empty commit
> message or killing the editor.  The order of things need to be
> to populate the index to be committed so that we can give
> preview in the commit log template upon 'commit -v', spawn the
> editor and get the final version of log, and then make a
> commit.  So it may or may not be doable -- I haven't thought
> about it through, and currently have not much incentive nor
> inclination to think about it myself right now.
> 
cp .git/index .git/pre-commit-index

and roll it back if the user aborts. Should work, but like you I don't need that functionality, so...

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se
Tel: +46 8-230225                  Fax: +46 8-230231

← back to recent threads