tusker
tusker

Reputation: 77

How to make Git not to list modified changes?

Git status will give me the list of changed files, among which I have some that has been changed but I don't want to commit, just keep it in the working directory as it is. It's annoying that before a commit I have to scan through the diffs of those files if something new had changed, or those modifications are only the ones I know about and don't want to commit.

Is there a way to tell Git these modifications are not to be committed, but let me know if there is any other change? Although I'm afraid there is no such thing as it would require another kind of index where these 'don't want to stage this changes' version files should be placed, but please let me know if there is something like that.

Upvotes: 2

Views: 429

Answers (4)

Kaz
Kaz

Reputation: 58666

The command

git diff --cached --name-only

will list the names of the files to which you have staged changes. We can expand that list of names into the shell command line if we wrap it with $(...) (command substitution syntax).

If you make more changes to those files and want to stage those changes, without worrying about other files that have modifications, you just reference that:

git add --patch $(git diff --cached --name-only)

since that is a mouthful, a function can be defined for it:

staged()
{
  git diff --cached --name-only
}

git add --patch $(staged)

To make use of this this idea, you will have to deal with the list of unwanted changes once. You stage the files that will be going into the commit. After that, $(staged) just refers to those files. E.g. git status $(staged) just gives you the status of those staged files, and git diff $(staged) just lists the uncommitted differences in those files.

You will have to pick those files out once though; no tool can read your mind.

If your git repository has a problem that a build system keeps modifying files that are under version control, then that's an issue that perhaps needs to be solved; those files perhaps should be taken out of version control.

Sometimes there are reasons for generated files to be checked into version control. However, most of those situations only make sense if there is a way of building the software, cleanly from scratch, such that those generated files are used (no generation takes place). If a clean build always generates the files, it is pointless for them to be checked in; they will just be a nuisance.

Upvotes: 0

hlovdal
hlovdal

Reputation: 28268

I have some that has been changed but I don't want to commit, just keep it in the working directory as it is. ... Is there a way to tell Git these modifications are not to be committed, but let me know if there is any other change?

You need to embrace temporary commits!

You absolutely should check in those temporary changes on your branch while working on it as separate, temporary commits (and with commit messages that clearly stands out that they are temporary). Later however, when completing the work on the branch, then those temporary commits can be removed.

Let's say the changes you are concerned with are various debug print statements (with printf, _logger.info, console.log or whatever logging mechanism that is appropriate), spread around all over the place in multiple files.

  • Axiom 1: Adding such temporary print statements while working on some feature is perfectly fine and normal.
  • Axiom 2: Not wanting to pollute the history of your project with those temporary print statements is good.

But not creating commits for those temporary changes is wrong because

  • Axiom 3: The only sensible way to handle such temporary changes is to check them in to git as temporary commits!

As an example assume you have been working on adding some foo functionality, have modified bar a bit and are now ready to complete the work. You have created a couple of temporary commits (that all start and end with the characters "===="1), so to remove those temporary commits you start an interactive rebase and are presented with the following list:

pick 10001 Started implementing foo
pick 10002 ==== debug foo ====
pick 10003 Finished implementing foo
pick 10004 Improved bar
pick 10005 ==== debug bar ====
pick 10006 ==== more foo debug ====
pick 10007 Removed unused baz
pick 10008 ==== more bar and foo debug ====

This is trivial to trim down to the following:

pick 10001 Started implementing foo
pick 10003 Finished implementing foo
pick 10004 Improved bar
pick 10007 Removed unused baz

which satisfies axiom 2.

If you're not constantly rewriting the (local) history in git, you're doing git wrong.

If you consider commits and branches as immutable objects you are missing out on the vast majority of git's benefits.

The benefits of checking in temporary changes as temporary commits are many:

  • There are no outstanding changes that prevents you from switching to a different branch.
  • They can be cherry-picked.
  • They can be rebased.
  • They can quickly be temporary disabled with git revert.
  • They can quickly dropped with interactive rebase (e.g. you no longer need to have the foo debug messages, but want to keep bar debugging).
  • They could eventually be shared with other people (they just need to be aware with your naming convention).
  • There is no git repo specific configuration.
  • You have the debug print statements available when running git bisect later for instance.
  • They have the same visibility as other commits in git log and gitk.

Thus you do not need "another kind of index", in fact the temporary commits are and should be treated as normal commits. The only "special" handling is to make the commit messages be enough different that they stand out as temporary commits, and to filter them out with interactive rebase at the end.

But what about conflicts during interactive rebase?

Use my script git-resolve-conflict-using-kdiff3. KDiff3 automatically resolves lines removed next to lines above/below that are changes (and if manual conflict resolution should be required KDiff3 is an awesome tool to use for that as well).


1 You can use whatever indicator you want, "====" is just a suggestion. It just needs to clearly stand out in the list of commits when doing an interactive rebase.

Upvotes: 8

Schleis
Schleis

Reputation: 43800

No, there isn't a way to do that.

You can do git update-index --assume-unchanged [path] which will ignore all changes to the file but if you want only some changes to be ignored and not others. Git doesn't work that way.

Upvotes: -1

Adrian J. Moreno
Adrian J. Moreno

Reputation: 14859

If you have files that should SOMETIMES not be committed, you're on your own. Like variables you've changed for your local development environment that are already part of source control.

If you have files that should NEVER be committed to the repository, then you need to add them to a .gitignore file.

At the root of the repository, create a file named .gitignore and add file or folder patterns to ignore. Your editor, VS Code or CLI, should show those files as no longer changed.

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*

# Dependency directories
node_modules/
jspm_packages/

Commit this one file and changes to those files will be ignored by anyone else that checks out the repo. Of course, they won't have those files at all, so if you have .env files that everyone needs to control environment variables, you should include a file like .env.EXAMPLE with placeholder variables for them to fill in as a local .env file.

Upvotes: 1

Related Questions