4

How can I tell git to ignore the current modification made to a file foobar, but not any future modifications?

I have in my worktree a file to which I made a small change that I do not want to commit back. I could use git update-index --assume-unchanged foobar, but then git will ignore any other change made to this file.

I would like to tell git to ignore only the current modification to foobar, and warn me if it has been changed in any other way.

So, considered that update-index --assume-unchanged is not applicable in this case, is there another way to tell git to see foobar as unchanged only as long as it has the current content or the current mtime?

gioele
  • 9,748
  • 5
  • 55
  • 80
  • It is *probably* not possible with plain git, because you need to store the old version somewhere (can only be in the index), but you don't want to commit it. The problem is that `git commit` just writes the whole index to the repository. But I might be wrong. – Yogu Nov 02 '14 at 13:15
  • It would be enough for git to record the current `mtime` as the `mtime` of the indexed version, so that git will check it again only when some application will change it. This is not completely future-proof, but good enough. – gioele Nov 02 '14 at 13:27
  • I doubt you can, you'd have to build something to do this. I don't think this is accounted for in any normal part of Git's workflow. You should typically be more aware of changes in your repo than this, I don't know why you'd want to hide the fact that a file is changing in the first place. – user229044 Nov 02 '14 at 13:29
  • The file is shared between two computers; it is being changed by an older version of an application that deletes configuration keys created by the newer version and that it does not understand. – gioele Nov 02 '14 at 13:31
  • @meagar: `git status` already uses `mtime` to understand if a file should be checked more in depth. If the current `mtime` is equal to the one stored (where?), it will be assumed as unchanged. c.f. the man page of `update-index`. – gioele Nov 02 '14 at 13:39
  • @gioele Yes, I'm well aware, but `update-index --assume-unchanged` supersedes this, and makes the `mtime` moot. You're asking for a combination of the two that does not exist. – user229044 Nov 02 '14 at 13:43
  • @meagar: I am not asking for a combination of the two, I am asking for an _alternative_ to `--assume-unchanged`. I rephrased the question to make this more clear. – gioele Nov 02 '14 at 13:54

2 Answers2

1

The file is shared between two computers; it is being changed by an older version of an application that deletes configuration keys created by the newer version and that it does not understand.

Then it would be better to not version that file at all, and rather version:

  • a template of that file
  • 2 value files (one for each computer)
  • a script able to generate the final file (which would remain private)
  • a .gitignore to declare a content filer driver, a smudge script, which would, on checkout automatically trigger the script and generates the right config file, with the right values, detecting on which computer it is being run.

smudge

(image from "Customizing Git Attributes" from the Git Book)

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
1

How can I tell git to ignore the current modification made to a file foobar, but not any future modifications?

If you place the "ignore" concept on a higher level than the low level store in index and repository level, then you get much higher flexibility and and you only have to adapt your work flow/process a little.

Let's say that I am working on my awesome new hello world program, but I need to add some debug while developing and this is not something I want to become part of the final delivery. What I do in such cases is to just check in that change as a normal commit but mark it in a special way, by prefix and postfixing the commit message with a string that clearly stands out from the other commit messages.

gitk screenshot

When I some time later want to finish the work I just filter out all those temporarily commits.

$ git checkout -b deliver work
Switched to a new branch 'deliver'
$ git rebase -i master

and then with the special marking of the commit messages it trivial to see what commits to remove:

pick fdbd12a Mininmal main.c
pick 21e3d6f hello world with arg support
pick a62ebac ========= DEBUG: print argc ========
pick 3160605 Use EXIT_SUCCESS
pick 0ec0ac6 constify message

# Rebase 8ce6878..0ec0ac6 onto 8ce6878
...

Which then gives me a clean delivery branch:

gitk screenshot

which I can merge into whatever branch I want to deliver to.


In your case you could for instance check in the change with new configuration keys as

git add yourfile
git commit -m "======== NEW CONFIG KEYS ========"

and then just filter out that commit when delivering, or possibly have a separate branch to work on where this commit is the only difference. E.g.

git checkout -b computer_new computer_old
git add yourfile
git commit -m "======== NEW CONFIG KEYS ========"
# do some work
git commit -am "some work 1"
git commit -am "some work 2"
git commit -am "some work 3"
# Rebase to put "NEW CONFIG KEYS" as the newest commit
git rebase -i computer_old

Change from

pick xxxxx ======== NEW CONFIG KEYS ========
pick xxxxx some work 1
pick xxxxx some work 2
pick xxxxx some work 3

to

pick xxxxx some work 1
pick xxxxx some work 2
pick xxxxx some work 3
pick xxxxx ======== NEW CONFIG KEYS ========

and then merge those new work commits back to computer_old

git checkout computer_old
git merge computer_new^

(branch^ means one commit older than newest commit on branch, e.g. merge up til including "the some work 3" commit).

hlovdal
  • 26,565
  • 10
  • 94
  • 165