1

I am working on a project where I edited some files that have been tracked by Git. Let's say that the edited tracked files are:

files1.py
file2.py
file3.py

All these files exist in the remote repository. However, I edited one of the files (saying file2.py) to be compatible with only my machine. So when committing, I don't want this file to be committed (I want the remote version of this file to be unchanged).
I know there are commands to do this like:
from this link

git add
git reset --file2.py

Or from this link:
git update-index --assume-unchanged "file2.py"

Yet, what I want is that this file will be ignored in every future commit without running the commands above every time.
Is there a way similar to .gitignore to make this file automatically ignored from being committed every time and always keep the remote version unchanged?

Yogi
  • 609
  • 1
  • 8
  • 21
singrium
  • 2,746
  • 5
  • 32
  • 45
  • There is no. `git update-index` is the only way. The better way is not to commit local files at all: https://stackoverflow.com/search?q=%5Bgit%5D+application+configuration – phd May 02 '19 at 15:16
  • @phd, thanks for the comment. How to change the mentioned file from tracked to local? – singrium May 02 '19 at 15:19
  • [`git rm --cached file2.py`](https://stackoverflow.com/questions/1143796/remove-a-file-from-a-git-repository-without-deleting-it-from-the-local-filesyste) but please understand that after you push the change everyone who pulls from that repository will get the file deleted. Even you when you checkout a different branch and then return back get the file deleted. – phd May 02 '19 at 15:25
  • Thank you for the explanation, I think the best and safest solution is to use `git update-index` – singrium May 02 '19 at 15:27

1 Answers1

1

You could do what you want by using a pre-commit hook:

pre-commit
This hook is invoked by git-commit, and can be bypassed with the --no-verify option. It takes no parameters, and is invoked before obtaining the proposed commit log message and making a commit. Exiting with a non-zero status from this script causes the git commit command to abort before creating a commit.

The simple code below unstages any changes to file2.py immediately prior to commit and refuses to create any new empty commit — that is, if the only file changed was file2.py.

#! /bin/bash

if ! git diff-index --quiet --cached HEAD -- file2.py; then
  echo Discarding file2.py changes from the index
  git reset HEAD -- file2.py

  if git diff-index --quiet --cached HEAD; then
    echo Aborting empty commit 1>&2
    exit 1
  fi
fi

Now that the academic question has been answered, I suggest using a different approach because the hook intentionally dumps the effort of controlling versions of the two different flavors of file2.py back onto the human user. If you want to do manual version control, why use git at all?

Instead, let git do the job it’s good at by placing your changes into a separate branch

git checkout --no-track -b feature/singrium origin/master

that as master changes (to which you catch up by running git fetch)

git checkout feature/singrium
git rebase origin/master

or into which you periodically merge changes from master.

git checkout feature/singrium
git merge origin/master

The difference between git rebase and git merge are in the respective histories they produce. If your changes to file2.py are small and localized to a small number of commits, the rebase approach keeps those commits together as a patch on top of whatever the latest master is. If your history is more unwieldy, merges may be easier, at least in the short term.

Community
  • 1
  • 1
Greg Bacon
  • 134,834
  • 32
  • 188
  • 245