73

Specifically, I maintain a git repository of my dotfiles. I recently started working on a new machine and cloned my repository on the same.

Now, I wish to make some changes to my dotfiles which are specific to this system only. These changes I wish to ignore in my repository.

Other changes that I make, should continue to be tracked and committed.

For example, in my .gitconfig, I have a setting as:

[push]
   default = simple

Now, on my new machine, the version of git being used it very old. It still not not support the setting simple for push. So, I'd like to change this, but only locally.

However, if I make any other changes to my .gitconfig, I'd like to keep track of those. Anyway I can achieve this?

EDIT:
I know of git update-index --assume-unchanged. The problem with it is that git will no longer track my file at all, until I reverse it. And then, it will track all changes.
I wish to ignore certain changes and track the rest.

rogerdpack
  • 62,887
  • 36
  • 269
  • 388
darnir
  • 4,870
  • 4
  • 32
  • 47
  • possible duplicate of [Committing Machine Specific Configuration Files](http://stackoverflow.com/questions/1396617/committing-machine-specific-configuration-files) – Senseful Aug 15 '14 at 01:03

4 Answers4

188

Try using this command:

git update-index --assume-unchanged FILENAME_TO_IGNORE

To reverse it (if you ever want to commit changes to it), use:

git update-index --no-assume-unchanged

UPDATE:

Here's how to list 'assume unchanged' files under current directory:

git ls-files -v | grep -E "^[a-z]"

As the -v option will use lowercase letters for 'assume unchanged' files.

rogerdpack
  • 62,887
  • 36
  • 269
  • 388
atupal
  • 16,404
  • 5
  • 31
  • 42
  • 1
    The problem with `git update-index --assume-unchanged` is that it will no longer track my file at all, until I reverse it. And then, it will track all changes. I wish to ignore certain changes and track the rest. – darnir Feb 13 '14 at 14:14
  • 4
    However this was exactly what I needed in my situation! A file my teammates use slows down the test suite by dozens of seconds, so I delete it all the time... but the fact that it's gone pollutes my git session. Not anymore though! – Dan Passaro Oct 15 '14 at 21:45
  • 7
    For the people who got here and thought "`--assume-unchanged` is perfect as I do want to ignore all changes to the file" try "--skip-worktree" instead. – Drew Mar 04 '16 at 03:45
  • 4
    `--skip-worktree` explained: http://stackoverflow.com/questions/13630849/git-difference-between-assume-unchanged-and-skip-worktree – CAD bloke Apr 06 '16 at 21:42
  • 2
    The problem I have with this is that `git checkout` still won't let me change branches if the changes to that file cause a conflict :T – Jorge Orpinel Pérez Jan 13 '17 at 06:47
  • @JorgeOrpinel You can try "git stash" before changing branches. – atupal Jan 15 '17 at 15:50
10

I don't believe there's a specific command that will 'untrack' certain changes to a file. However, there's no reason that you couldn't create a local branch into which you pull changes from your remotes, but never send any changes back.

Peter Bratton
  • 6,302
  • 6
  • 39
  • 61
  • 2
    Duh! That's exactly what I need! Sending those changes to a branch! Thanks! I've been over-engineering this situation. – darnir Feb 13 '14 at 15:03
  • 4
    Please explain. If you have a local branch that you only pull changes in, but never send any changes back, how can you transfer the changes you made in that local branch to the main code base? – blipbloop Apr 29 '17 at 00:27
5

Here is an alternative solution to your specific problem. Place machine-config configuration in a ~/.gitconfig.local file, and then put the following in your version-controlled ~/.gitconfig:

[include]
    path = ~/.gitconfig.local

This will tell Git to treat anything it finds in ~/.gitconfig.local as if it were in ~/.gitconfig. Yes, you can override settings. No, it does not require the file to exist (Git will silently ignore the setting if there is no ~/.gitconfig.local).

See here for more information about [include].

I follow this strategy in my configurations for Emacs, Zsh, Git, Tmux, etc., so that they are customizable without the need to modify version-controlled files. To accomplish this, I have init.local.el, .zshrc.local, .gitconfig.local, .tmux.local.conf, and so on.

Community
  • 1
  • 1
Resigned June 2023
  • 4,638
  • 3
  • 38
  • 49
0

As suggested by Peter you can keep those machine specific changes in a branch. Obviously you will have to be careful to strictly separate changes to those machine specific files from the "mainline". There are 2 ways for doing this:

  1. Keep rebasing the branch whenever you change the mainline (this would be my preference)
  2. Keep merging mainline changes into the branch (but obviously never merge in the other direction)
kynan
  • 13,235
  • 6
  • 79
  • 81