0

I have over 100+ files and directories to commit. But I don't want to commit 2 directories for the time being. How can I skip or exclude these directories for this commit?

No, it doesnt belong in a .gitignore as I'm just doing it for this instance.

Patoshi パトシ
  • 21,707
  • 5
  • 29
  • 47

1 Answers1

2

TL;DR

Make a short list of the files you do want to add, add them, and commit. For instance, start with git status --short > /tmp/list, then open /tmp/list in your favorite editor. Replace the M in front of each file that you do want to add with git add. Delete the entire line for each file that you don't want to add. Then run sh /tmp/list to execute all the git add commands. Run git status again, without --short this time if you prefer, to see what you've got staged.

Long

You don't exclude them. You keep them around, you just don't change them. This is easier than it sounds.

In Git, every commit is a complete snapshot of every file. (Well, of every file in that commit.) The change between any commit and its parent is something Git figures out later, when you ask it: "what's the difference between the complete snapshot X, and the complete snapshot Y?" That is:

...--X--Y   <-- somebranch

Here snapshot X has every file in the form it had as of X, and snapshot Y has every file in the form it had as of Y. To figure out what changed, Git will in effect subtract X from Y.

If you omit a series of files in commit Y, the answer to what changed? is, or includes: delete all those files.


The way Git builds new commits is using something that people variously call the index, the staging area, or sometimes the cache. You start by doing a git checkout:

$ git checkout somebranch

This does several things, all more or less simultaneously:

  • Puts you "on" that branch, so that git status says on branch somebranch.
  • Fills in your work-tree—the directory in which you do all your work—from the tip commit of branch somebranch.
  • Fills in your index aka staging area from that same commit.1

The way that Git knows that you are "on" that branch is that Git attaches the special file HEAD to that branch name. The branch name itself identifies the tip commit, e.g., commit Y as in the drawing above. Because HEAD is attached to branchname, both of these resolve to "commit Y" at this point.

Note that at this point, all the files in your HEAD commit (commit Y) exactly match all the files in your index, and those match all the files—well, all the tracked files—in your work-tree. Any untracked file in your work-tree is a file that is not in your index (and thus is not in commit Y either, since your index matches commit Y).


1Git will allow your index and work-tree to differ from your current commit after git checkout in some cases, but not always. See Checkout another branch when there are uncommitted changes on the current branch for details.


Now suppose you change some, perhaps even many, files in your work-tree. What happens to the copies of those files in your index? The answer is: nothing happens! Those files in your index still match the current commit Y.

If you have something in one file that you want in a new commit Z, you must now git add the files from the work-tree into the index. This overwrites the copy that was in the index, using the one from the work-tree instead.

If you have many things in many files, you must git add each of those files, or use some sort of en-masse "add all files" operation. Each added file gets copied over the existing one, so that the work-tree version is now the version in the index.

When you finally run git commit, Git packages up whatever is in the index right now and uses that for the new commit Z. The new commit's parent is the current commit Y, and as soon the commit is saved, Git updates the current branch name so that it points to the new commit Z instead of the old commit Y. Your HEAD remains attached to the branch name, so now you have:

...--X--Y--Z   <-- branchname (HEAD)

and your index completely matches your current commit. Your work-tree is different, just as is allowed in the question linked in footnote 1.

You can now git add more files, if you like. Note that unlike committed files, whatever is in the work-tree is not stored anywhere permanent, so before you overwrite whatever you have not committed, make sure that's OK to do.

torek
  • 448,244
  • 59
  • 642
  • 775
  • lol, that's ridiculous amount of steps to just exclude 2 directories from getting commited. what if i did a **git commit -am** ? and then uncommit the 2 directories? – Patoshi パトシ Mar 29 '18 at 18:56
  • 1
    It's no steps at all. Just *don't* `git add` the files you don't want added. Do not use `git commit -a`: that effectively means `git add -u` (add all that Git knows about) followed by `git commit`. – torek Mar 29 '18 at 19:27