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.
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.
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.
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:
git status
says on branch somebranch
.somebranch
.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.