threads / bug / 38114

GIT: ignoring changes in tracked files and bug report

Subject: GIT: ignoring changes in tracked files and bug report

## tl;dr

19 messages between Dec 4, 2014 and Dec 11, 2014.

replies: 18people: 6as markdown or json

Sérgio Basto· Dec 4, 2014, 22:42 UTC · lore

Hi, I'm trying find a solution where I can change file in a devel environment , and not commit it into git .

git update-index --assume-unchanged <file> 
is one solution , not the best solution but one solution. 
I add 2 files that I want ignore on commits 

git update-index --assume-unchanged configurations/local.defs git update-index --assume-unchanged processor/default.defs

git diff -a is clean git diff . is clean

git commit -a nothing added to commit but git commit . # Changes to be committed: # modified: configurations/local.defs # modified: processor/default.defs

this is a bug ? 

Anyway what is best way to deal with some files where we want change locally and not commit in git . The solution of have one environment variable that says if we are in devel or in production , and system read the variable and choose the files to read can't be applied in my case, and is a no solution , is save a variable outside of source code which I can't.

Thanks,
-- 
Sérgio M. B.
Sérgio Basto· Dec 5, 2014, 06:12 UTC · re: Sérgio Basto · lore

bug report on update-index --assume-unchanged

Hi,

I add 2 files that I want ignore on commits git update-index --assume-unchanged configurations/local.defs git update-index --assume-unchanged processor/default.defs

git diff -a is clean git diff . is clean git commit -a

nothing added to commit
but 

git commit . # Changes to be committed: # modified: configurations/local.defs # modified: processor/default.defs

this is a bug .
thanks
-- 
Sérgio M. B.
Johannes Sixt· Dec 5, 2014, 06:55 UTC · re: Sérgio Basto · lore

Re: bug report on update-index --assume-unchanged

Am 05.12.2014 07:12, schrieb Sérgio Basto:
Show 22 quoted lines
> Hi,
>
> I add 2 files that I want ignore on commits
> git update-index --assume-unchanged configurations/local.defs
> git update-index --assume-unchanged processor/default.defs
>
> git diff -a
> is clean
> git diff .
> is clean
> git commit -a
>
> nothing added to commit
>
> but
>
> git commit .
> # Changes to be committed:
> #       modified:   configurations/local.defs
> #       modified:   processor/default.defs
>
> this is a bug .

Actually, it's a user error. When you set --assume-unchanged, then you give a promise to git that you do not change the files, and git does not have to check itself whether there is a change.

But since you did not keep your promise, you get what you deserve. ;-)

So, to follow-up on your nearby post: --assume-unchanged is *not* a tool to avoid accidentally committing changes to files that are tracked.

-- Hannes
Duy Nguyen· Dec 5, 2014, 10:52 UTC · re: Johannes Sixt · lore

Re: bug report on update-index --assume-unchanged

On Fri, Dec 5, 2014 at 1:55 PM, Johannes Sixt <j6t@kdbg.org> wrote:
Show 5 quoted lines
> Actually, it's a user error. When you set --assume-unchanged, then you give
> a promise to git that you do not change the files, and git does not have to
> check itself whether there is a change.
>
> But since you did not keep your promise, you get what you deserve. ;-)

You are correct about the original idea behind --assume-unchanged. But over the time I think we bend over a bit and sort of support these use cases. For example, aecda37 (do not overwrite files marked "assume unchanged" - 2010-05-01). The change is one-liner, so I don't mind doing it.

-- 
Duy
Sérgio Basto· Dec 5, 2014, 16:57 UTC · re: Duy Nguyen · lore

Re: bug report on update-index --assume-unchanged

Hi, On Sex, 2014-12-05 at 17:52 +0700, Duy Nguyen wrote:

Show 6 quoted lines
> On Fri, Dec 5, 2014 at 1:55 PM, Johannes Sixt <j6t@kdbg.org> wrote:
> > Actually, it's a user error. When you set --assume-unchanged, then you give
> > a promise to git that you do not change the files, and git does not have to
> > check itself whether there is a change.
> >
> > But since you did not keep your promise, you get what you deserve. ;-)

No, I marked with assume-unchanged *after* change the file , and not before. Else don't see what is the point of assume-unchanged if you really don't change the file.

Show 5 quoted lines
> You are correct about the original idea behind --assume-unchanged. But
> over the time I think we bend over a bit and sort of support these use
> cases. For example, aecda37 (do not overwrite files marked "assume
> unchanged" - 2010-05-01). The change is one-liner, so I don't mind
> doing it.
I think is the right thing 
Thanks,
-- 
Sérgio M. B.
Junio C Hamano· Dec 5, 2014, 18:30 UTC · re: Sérgio Basto · lore

Re: bug report on update-index --assume-unchanged

Sérgio Basto <sergio@serjux.com> writes:
Show 12 quoted lines
> On Sex, 2014-12-05 at 17:52 +0700, Duy Nguyen wrote: 
>> On Fri, Dec 5, 2014 at 1:55 PM, Johannes Sixt <j6t@kdbg.org> wrote:
>> > Actually, it's a user error. When you set --assume-unchanged, then you give
>> > a promise to git that you do not change the files, and git does not have to
>> > check itself whether there is a change.
>> >
>> > But since you did not keep your promise, you get what you deserve. ;-)
>
>
> No, I marked with assume-unchanged *after* change the file , and not
> before. Else don't see what is the point of assume-unchanged if you
> really don't change the file. 
That "unchanged" is relative to what is in the index.

Your promise is "these paths I will not modify" and in return you gain performance in "git status" as the promise allows Git not to check with lstat() if the files in the workng tree was modified and instead assume that you didn't change them. That is the point of assume-unchanged bit.

If however you did something that made Git notice that you changed these paths marked with assume-unchanged bit anyway, then Git will, well, notice that they are not "unchanged" as you promised.

Philip Oakley· Dec 5, 2014, 20:04 UTC · re: Junio C Hamano · lore

Re: bug report on update-index --assume-unchanged

From: "Junio C Hamano" <gitster@pobox.com>
Show 30 quoted lines
> Sérgio Basto <sergio@serjux.com> writes:
>
>
>> On Sex, 2014-12-05 at 17:52 +0700, Duy Nguyen wrote:
>>> On Fri, Dec 5, 2014 at 1:55 PM, Johannes Sixt <j6t@kdbg.org> wrote:
>>> > Actually, it's a user error. When you set --assume-unchanged, then
>>> > you give
>>> > a promise to git that you do not change the files, and git does
>>> > not have to
>>> > check itself whether there is a change.
>>> >
>>> > But since you did not keep your promise, you get what you deserve.
>>> > ;-)
>>
>>
>> No, I marked with assume-unchanged *after* change the file , and not
>> before. Else don't see what is the point of assume-unchanged if you
>> really don't change the file.
>
> That "unchanged" is relative to what is in the index.
>
> Your promise is "these paths I will not modify" and in return you
> gain performance in "git status" as the promise allows Git not to
> check with lstat() if the files in the workng tree was modified and
> instead assume that you didn't change them.  That is the point of
> assume-unchanged bit.
>
> If however you did something that made Git notice that you changed
> these paths marked with assume-unchanged bit anyway, then Git will,
> well, notice that they are not "unchanged" as you promised.

The problem here is that there is no guidance on what those actions are that may make git 'notice'. The man page git-update-index isn't as clear as it could be. Using --really-refresh being one option that would make git notice, but I wouldn't know when that is used.

Part of the implied question is why "git commit ." would notice when when "git commit -a" didn't appear to. So it's unclear as to what the user should have expected.

(Note, I don't use assume-unchanged myself so this is more about supporting the user/manual clarification. It is mentioned moderately often on stackoverflow etc.)

-- Philip

Junio C Hamano· Dec 5, 2014, 21:05 UTC · re: Philip Oakley · lore

Re: bug report on update-index --assume-unchanged

"Philip Oakley" <philipoakley@iee.org> writes:
> The problem here is that there is no guidance on what those actions are
> that may make git 'notice'....

I think the guidance the users need is the one j6t has given already in the upthread: "If you are promising Git you are not going to touch a path, do not touch it. Bad things may happen."

There is no need to say "if you touched this way or that way, then you might get lucky." because the "lucky" part is not designed. As we find more codepaths that can rely on the promise by the user, we may decide to take advantage of that promise even further and the "lucky/unlucky" equation _will_ change when that happens.

Philip Oakley· Dec 5, 2014, 21:52 UTC · re: Junio C Hamano · lore

Re: bug report on update-index --assume-unchanged

From: "Junio C Hamano" <gitster@pobox.com>
Show 16 quoted lines
> "Philip Oakley" <philipoakley@iee.org> writes:
>
>> The problem here is that there is no guidance on what those actions 
>> are
>> that may make git 'notice'....
>
> I think the guidance the users need is the one j6t has given already
> in the upthread: "If you are promising Git you are not going to
> touch a path, do not touch it.  Bad things may happen."
>
> There is no need to say "if you touched this way or that way, then
> you might get lucky." because the "lucky" part is not designed.  As
> we find more codepaths that can rely on the promise by the user, we
> may decide to take advantage of that promise even further and the
> "lucky/unlucky" equation _will_ change when that happens.
>

However the man page's statement 'When the "assume unchanged" bit is on, Git stops checking the working tree files for possible modifications, so you need to manually unset the bit to tell Git when you change the working tree file.' can easily be understood the way Sergio has described. Git stops checking so it won't notice any changes, which is a contract it doesn't keep.

Perhaps the man page itself needs rewording to be more firm that the user should NOT change the file. The contract is with the user not to change, rather than a contract by Git not to look.

Even with that man page change, it would not solve many of the user X-Y problems where what they want is an "--ignore-this" flag for a file which does give that alternate contract that 'git won't look until the flag has been cleared.

-- Philip

Andreas Schwab· Dec 5, 2014, 22:18 UTC · re: Philip Oakley · lore

Re: bug report on update-index --assume-unchanged

"Philip Oakley" <philipoakley@iee.org> writes:
Show 6 quoted lines
> However the man page's statement 'When the "assume unchanged" bit is on,
> Git stops checking the working tree files for possible modifications, so
> you need to manually unset the bit to tell Git when you change the working
> tree file.' can easily be understood the way Sergio has described. Git
> stops checking so it won't notice any changes, which is a contract it
> doesn't keep.

The contract is: when you change the working tree file, you must tell Git about it. Failure to do so is a breach of the contract.

Andreas.
-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."
Sérgio Basto· Dec 6, 2014, 00:45 UTC · re: Philip Oakley · lore

Re: bug report on update-index --assume-unchanged

On Sex, 2014-12-05 at 20:48 +0000, Philip Oakley wrote:
Show 12 quoted lines
> The problem here is that there is no guidance on what those actions
> are
> that may make git 'notice'. The man page git-update-index isn't as
> clear
> as it could be. Using --really-refresh being one option that would
> make
> git notice, but I wouldn't know when that is used.
> 
> Part of the implied question is why "git commit ." would notice when
> when "git commit -a" didn't appear to. So it's unclear as to what the 
> user should have expected.
> 
I agree with this sentence, this is a bug because:

git commit -a ( and -a means all ) is incoherent with "git commit ." This is stupid because when I want commit part of the tree, commit includes one file that is not included when I say to commit all . So maybe you should fix, git commit -a to be coherent .

> (Note, I don't use assume-unchanged myself so this is more about 
> supporting the user/manual clarification. It is mentioned moderately 
> often on stackoverflow etc.)
yeap  

Sorry I don't have time to read all messages in thread , but I'm going to test git with the patch suggest in this thread , at least, I solve "my" problem for some time ...

Thanks,  
-- 
Sérgio M. B.
Philip Oakley· Dec 6, 2014, 13:06 UTC · re: Sérgio Basto · lore

Re: bug report on update-index --assume-unchanged

From: "Sérgio Basto" <sergio@serjux.com>
[..]
Show 10 quoted lines
>> Part of the implied question is why "git commit ." would notice when
>> when "git commit -a" didn't appear to. So it's unclear as to what the
>> user should have expected.
>>
> I agree with this sentence, this is a bug because:
>
> git commit -a ( and -a means all ) is incoherent with "git commit ."
> This is stupid because when I want commit part of the tree, commit
> includes one file that is not included when I say to commit all .
> So maybe you should fix, git commit -a to be coherent .

Ultimately this (-a vs '.' with --assume-unchanged) is not a 'bug', because it does as planned. However the documenation is 'wrong' or at least misguides many readers.

Thank you for bring it to the list's attention. [..]

Show 5 quoted lines
>
> Sorry I don't have time to read all messages in thread ,
> but I'm going to test git with the patch suggest in this thread , at
> least, I solve "my" problem for some time ...
>

My patch, and Junio's 'squash' are to correct the documentation, and especially remove the line about it having an "ignore" capability, which is a promise not kept (your -a vs '.' !).

I'll be updating the documenation patch today for review, though that 
doesn't solve the wider problem of:
    - 'how to temporarily ignore changes to a tracked file'.
--
Philip 
Junio C Hamano· Dec 5, 2014, 21:19 UTC · re: Junio C Hamano · lore

Re: bug report on update-index --assume-unchanged

Junio C Hamano <gitster@pobox.com> writes:
> If however you did something that made Git notice that you changed
> these paths marked with assume-unchanged bit anyway, then Git will,
> well, notice that they are not "unchanged" as you promised.

By the way, this cuts both ways. I would not bother checking with the current codebase, but I know it used to be that when we have a blob object name and need a temporary file that holds the content for read-only purpose (e.g. passing a pair of files to external diff driver), we allowed Git to reuse files in the working tree whose blob object name we knew. This is of course because it is faster than inflating the blob contents out of the object store and writing a new file.

That codepath is allowed to "borrow" the working tree file as such a temporary file for read-only purpose, when a file is stat-clean (i.e. its contents is known to match the blob object recorded in the index). A file with assume-unchanged bit set is treated exactly the same way, because the user promised not to modify it.

If the user broke the promise, then an external diff driver would have been given a file whose contents does not actually match the wanted blob object, resulting in an incorrect diff output.

Sérgio Basto· Dec 5, 2014, 21:39 UTC · re: Junio C Hamano · lore

Re: bug report on update-index --assume-unchanged

On Sex, 2014-12-05 at 10:30 -0800, Junio C Hamano wrote:
> Your promise is "these paths I will not modify" and in return you
> gain performance in "git status"

yeah so --assume-unchanged is for administrators of git , like I write I change first and --assume-unchanged after and never change it again . But if it is a tool for administration of git , I don't what to say ... put it in a gitadmin command .

I hate git and this is one one the reason . 
-- 
Sérgio M. B.
Junio C Hamano· Dec 5, 2014, 21:52 UTC · re: Sérgio Basto · lore

Re: bug report on update-index --assume-unchanged

Sérgio Basto <sergio@serjux.com> writes:
Show 5 quoted lines
> On Sex, 2014-12-05 at 10:30 -0800, Junio C Hamano wrote:
>> Your promise is "these paths I will not modify" and in return you
>> gain performance in "git status"
>
> yeah  so  --assume-unchanged is for administrators of git ,...
Not at all.

Administrators would typically not know (and they would not want to know) what part of your particular project tree you as an individual developer is not working on day to day.

This was added primarily by normal users (or as a response to a request from normal users) on slow filesystems (e.g. Cygwin). When they are working on one part of their project tree and know they are not touching other parts, they wanted to skip slowness of having to lstat(2) all paths in the project tree to detect what changed during "git status".

Junio C Hamano· Dec 5, 2014, 18:33 UTC · re: Duy Nguyen · lore

Re: bug report on update-index --assume-unchanged

Duy Nguyen <pclouds@gmail.com> writes:
Show 5 quoted lines
> You are correct about the original idea behind --assume-unchanged. But
> over the time I think we bend over a bit and sort of support these use
> cases. For example, aecda37 (do not overwrite files marked "assume
> unchanged" - 2010-05-01). The change is one-liner, so I don't mind
> doing it.

I think that was a misguided change to make the semantics muddy and to break the existing users who use the bit for its intended purpose (i.e. to avoid lstat() by promising that it is not necessary), and not "bending over to support". Offhand, I doubt we would want to add more of the same kind.

Nguyễn Thái Ngọc Duy· Dec 5, 2014, 10:56 UTC · re: Sérgio Basto · lore

[PATCH] commit: ignore assume-unchanged files in "commmit <file>" mode

In the same spirit of 7fce6e3 (commit: correctly respect skip-worktree bit - 2009-12-14), if a file is marked unchanged, skip it.

Noticed-by: Sérgio Basto <sergio@serjux.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/commit.c                         |  2 +-
 t/t2106-update-index-assume-unchanged.sh | 10 ++++++++++
 2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/builtin/commit.c b/builtin/commit.c
index e108c53..ee3de12 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -252,7 +252,7 @@ static int list_paths(struct string_list *list, const char *with_tree,
 		if (!ce_path_match(ce, pattern, m))
 			continue;
 		item = string_list_insert(list, ce->name);
-		if (ce_skip_worktree(ce))
+		if (ce->ce_flags & (CE_VALID | CE_SKIP_WORKTREE))
 			item->util = item; /* better a valid pointer than a fake one */
 	}
 
diff --git a/t/t2106-update-index-assume-unchanged.sh b/t/t2106-update-index-assume-unchanged.sh
index 99d858c..dc332f5 100755
--- a/t/t2106-update-index-assume-unchanged.sh
+++ b/t/t2106-update-index-assume-unchanged.sh
@@ -21,4 +21,14 @@ test_expect_success 'do not switch branches with dirty file' \
 	 git update-index --assume-unchanged file &&
 	 test_must_fail git checkout master'
 
+test_expect_success 'commit <paths> ignore assume-unchanged files' '
+	: >anotherfile &&
+	git add anotherfile &&
+	echo dirty >anotherfile &&
+	git commit -m one -- file anotherfile &&
+	git diff --name-only HEAD^ HEAD >actual &&
+	echo anotherfile >expected &&
+	test_cmp expected actual
+'
+
 test_done
-- 
2.2.0.60.gb7b3c64
Sérgio Basto· Dec 9, 2014, 02:44 UTC · re: Nguyễn Thái Ngọc Duy · lore

Re: [PATCH] commit: ignore assume-unchanged files in "commmit <file>" mode

On Sex, 2014-12-05 at 17:56 +0700, Nguyễn Thái Ngọc Duy wrote: 
Show 42 quoted lines
> In the same spirit of 7fce6e3 (commit: correctly respect skip-worktree
> bit - 2009-12-14), if a file is marked unchanged, skip it.
> 
> Noticed-by: Sérgio Basto <sergio@serjux.com>
> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
> ---
>  builtin/commit.c                         |  2 +-
>  t/t2106-update-index-assume-unchanged.sh | 10 ++++++++++
>  2 files changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/builtin/commit.c b/builtin/commit.c
> index e108c53..ee3de12 100644
> --- a/builtin/commit.c
> +++ b/builtin/commit.c
> @@ -252,7 +252,7 @@ static int list_paths(struct string_list *list, const char *with_tree,
>  		if (!ce_path_match(ce, pattern, m))
>  			continue;
>  		item = string_list_insert(list, ce->name);
> -		if (ce_skip_worktree(ce))
> +		if (ce->ce_flags & (CE_VALID | CE_SKIP_WORKTREE))
>  			item->util = item; /* better a valid pointer than a fake one */
>  	}
>  
> diff --git a/t/t2106-update-index-assume-unchanged.sh b/t/t2106-update-index-assume-unchanged.sh
> index 99d858c..dc332f5 100755
> --- a/t/t2106-update-index-assume-unchanged.sh
> +++ b/t/t2106-update-index-assume-unchanged.sh
> @@ -21,4 +21,14 @@ test_expect_success 'do not switch branches with dirty file' \
>  	 git update-index --assume-unchanged file &&
>  	 test_must_fail git checkout master'
>  
> +test_expect_success 'commit <paths> ignore assume-unchanged files' '
> +	: >anotherfile &&
> +	git add anotherfile &&
> +	echo dirty >anotherfile &&
> +	git commit -m one -- file anotherfile &&
> +	git diff --name-only HEAD^ HEAD >actual &&
> +	echo anotherfile >expected &&
> +	test_cmp expected actual
> +'
> +
>  test_done
works great many thanks, 
-- 
Sérgio M. B.
Philip Oakley· Dec 11, 2014, 23:21 UTC · re: Sérgio Basto · lore

Re: [PATCH] commit: ignore assume-unchanged files in "commmit <file>" mode

From: "Sérgio Basto" <sergio@serjux.com> Sent: Tuesday, December 09, 
2014 2:44 AM
Show 51 quoted lines
> On Sex, 2014-12-05 at 17:56 +0700, Nguyễn Thái Ngọc Duy wrote:
>> In the same spirit of 7fce6e3 (commit: correctly respect 
>> skip-worktree
>> bit - 2009-12-14), if a file is marked unchanged, skip it.
>>
>> Noticed-by: Sérgio Basto <sergio@serjux.com>
>> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
>> ---
>>  builtin/commit.c                         |  2 +-
>>  t/t2106-update-index-assume-unchanged.sh | 10 ++++++++++
>>  2 files changed, 11 insertions(+), 1 deletion(-)
>>
>> diff --git a/builtin/commit.c b/builtin/commit.c
>> index e108c53..ee3de12 100644
>> --- a/builtin/commit.c
>> +++ b/builtin/commit.c
>> @@ -252,7 +252,7 @@ static int list_paths(struct string_list *list, 
>> const char *with_tree,
>>  if (!ce_path_match(ce, pattern, m))
>>  continue;
>>  item = string_list_insert(list, ce->name);
>> - if (ce_skip_worktree(ce))
>> + if (ce->ce_flags & (CE_VALID | CE_SKIP_WORKTREE))
>>  item->util = item; /* better a valid pointer than a fake one */
>>  }
>>
>> diff --git a/t/t2106-update-index-assume-unchanged.sh 
>> b/t/t2106-update-index-assume-unchanged.sh
>> index 99d858c..dc332f5 100755
>> --- a/t/t2106-update-index-assume-unchanged.sh
>> +++ b/t/t2106-update-index-assume-unchanged.sh
>> @@ -21,4 +21,14 @@ test_expect_success 'do not switch branches with 
>> dirty file' \
>>  git update-index --assume-unchanged file &&
>>  test_must_fail git checkout master'
>>
>> +test_expect_success 'commit <paths> ignore assume-unchanged files' '
>> + : >anotherfile &&
>> + git add anotherfile &&
>> + echo dirty >anotherfile &&
>> + git commit -m one -- file anotherfile &&
>> + git diff --name-only HEAD^ HEAD >actual &&
>> + echo anotherfile >expected &&
>> + test_cmp expected actual
>> +'
>> +
>>  test_done
>
>
> works great many thanks,
>
Junio: Given that this patch avoids the user surprise that the `commit 
.` and `commit -a` produced unexpectedly different effects, should it 
also be included in the --assume unchanged patches? Or is the test 
inappropriate?

I'm guessing that there will still be other potential 'gotcha' code paths that would still produce surprise though.

Philip 

← back to recent threads