1

I have some object files and assembly files that I have committed for the first version. I don't want to commit changes to these files as I make changes to my project and update the other source files. However, I do want to keep them in my repository, in the first commit.

The two options I know of are:

  1. Remove them from the repository:1
    a. Update .gitignore
    b. git rm --cached <file> or...

  2. git update-index --assume-unchanged <file>2

Both of these can be seen in this question: Ignore files that have already been committed to a Git repository

and here:

Git: ignore specific file(s) both on Commit and Pull


1 ...However, I'd like them to stay within the repository and they will be removed when the next commit is completed.

2 ...This option, as per this answer from this question notes:

Assume-unchanged should not be abused for an ignore mechanism. It is "I know my filesystem operations are slow... Especially, it is not a promise by Git that Git will always consider these paths are unmodified... it reserves the right to report that the path has been modified (as a result, "git commit -a" is free to commit that change).

So is there a proper way to commit those files once, keep them in that state in the repository, and then ignore any further changes to them?

I did find some information here: https://gist.github.com/canton7/1423106

But it seems... involved. Is there no actual option that git contains that works as though --assume-unchanged does, but without lying to git?

Community
  • 1
  • 1
Nathan Lutterman
  • 1,855
  • 4
  • 23
  • 38

2 Answers2

2

As of Git 1.7.0 you have a third option: sparse checkout.

With sparse checkout you basically tell Git to exlude a certain set of files from the working tree. Those files will still be part of the repository but they won't show up in your working directory.

Internally, sparse checkout uses the skip-worktree flag to mark all the excluded files as always updated. From the documentation:

When reading an entry, if it is marked as skip-worktree, then Git pretends its working directory version is up to date and read the index version instead.

Here's how you enable sparse checkout in an existing repository:

  1. Enable sparse checkout in your repository with git config core.sparseCheckout true
  2. Create a .git/info/sparse-checkout file containing the paths to include in the working directory. In your case, you would have to include everything and then exclude the specific file by adding a ! in front of its path:

    /* !path-to-the-file-to-exclude

  3. Update your working directory with git read-tree -mu HEAD

Note that if you want to get back the excluded file, it's not enough to simply disable sparse checkout with git config core.sparseCheckout false. You'll first have to modify the .git/info/sparse-checkout file to include everything by only specifying /*, update your working tree with git read-tree -mu HEAD and then disable sparse checkout in your configuration file.

Enrico Campidoglio
  • 56,676
  • 12
  • 126
  • 154
1

There a few options:

--assume-unchanged

Since git track content, once you add the content to git it is stated to be tracked. one way to turn-off the tracking is to set the --assume-unchanged on the desired resource.

Tip:

#
# list assumed unchanged files
#
git ls-files -v | grep ^h

.gitignore & git rm --cached

Another way is to delete and commit the deleted files so git will stop tracking it as well.

# Delete desired content to untrack
git rm --cached <path>

# commit the deleted content
git commit -m "Deleted ..."

--skip-worktree

git update-index --skip-worktree <path>

--[no-]skip-worktree
When one of these flags is specified, the object name recorded for the paths are not updated.

Instead, these options set and unset the "skip-worktree" bit for the paths. See section "Skip-worktree bit" below for more information.


Skip-worktree bit

Skip-worktree bit can be defined in one (long) sentence: When reading an entry, if it is marked as skip-worktree, then Git pretends its working directory version is up to date and read the index version instead.

To elaborate, reading means checking for file existence, reading file attributes or file content. The working directory version may be present or absent.

If present, its content may match against the index version or not. Writing is not affected by this bit, content safety is still first priority.

Note that Git can update working directory file, that is marked skip-worktree, if it is safe to do so (i.e. working directory version matches index version)

Although this bit looks similar to assume-unchanged bit, its goal is different from assume-unchanged bit’s. Skip-worktree also takes precedence over assume-unchanged bit when both are set

CodeWizard
  • 128,036
  • 21
  • 144
  • 167
  • Since when it's OK to _copy_ someone else's answer into your own? Please remove the copied parts and either link to the relevant answer directly or don't bother. – Enrico Campidoglio Mar 07 '16 at 09:08
  • Np, i added a message in your answer and gave you a full credit for it. Ill remove it. – CodeWizard Mar 07 '16 at 09:10