0

I pulled in a large number of scripts and made slight changes to all of them, which I wish to preserve.

Git has tracked these changes, in addition to a new script that I created, which is marked as untracked.

This made me wonder if there is a way I could add (and subsequently commit) only those files marked as modified and ignore the untracked file(s) / all other files for the time being.

In this instance, I am aware that I could simply commit the untracked file first, which would mean that only the modified files are left and that I could then commit those, but for those instances where there is more than one untracked file, I wonder if this is possible.

In short: how can I commit modified files only, preserving everything else as is?

Mus
  • 7,290
  • 24
  • 86
  • 130
  • Only what you *added* will be committed. If you want some changes not to be in the commit, just don't add them. You can verify what's been added with `git diff --staged` – Romain Valeri Jul 15 '21 at 13:51
  • @RomainValeri Yes, I am aware of this but my question focuses on the status of specific files. Let's say that I have 45 files which are modified and a further 50 which are untracked. If I `git add .`, all 95 files will be added to the commit, which I don't want. What I want to be able to do is just add the `modified` files only. – Mus Jul 15 '21 at 14:00
  • https://stackoverflow.com/search?q=%5Bgit%5D+commit+only+modified+files – phd Jul 15 '21 at 14:25

2 Answers2

1

That's what git commit -a does: adds and commits all modified files. (A modified file is, by definition, tracked; git has no basis for determining if an untracked file is modified or not, because "modification" is relative to HEAD.)

chepner
  • 497,756
  • 71
  • 530
  • 681
  • Add does exactly the same thing in both cases. The index is an index: object id's for tracked paths. Add adds the object to the object db and sets the index entry for that path to point to it. – jthill Jul 16 '21 at 01:07
  • Hm. I was thinking there was a distinction between untracked and tracked that `git add` changed, but maybe that's a distinction that `git status` creates? It does make sense to say `git add` simply adds a new blob to the index (conditional on the file differing from what's currently in `HEAD` or the index). – chepner Jul 16 '21 at 02:17
  • It's tracked if it's got an index entry. Add makes or updates index entries for what it adds. So if it wasn't tracked before, if it didn't have an index entry before, if it wasn't in the index before, it is now, but the "it" is the pathname and the (only, here, since there's no merge in flight) object id that goes with it. The object itself is in the object db, that's where all objects are. – jthill Jul 16 '21 at 02:57
0

You can use git stash for that as a simple FIFO stack (first in, first out) incombination with --keep-index switch:

TL;DR:

  • git stash push --keep-index
  • add + stash the rest
  • restore first stash + commit
  • restore second stash + git reset HEAD

Example with a dummy repo from scratch:

# dummy repo
$ pushd /tmp
$ mkdir repo
$ pushd repo

$ git init
Initialized empty Git repository in /tmp/repo/.git/
$ git commit -m "init" --allow-empty
[master (root-commit) d16af78] init
$ echo "initial" >> text.txt
$ git add text.txt 
$ git commit -m "initial data"
[master 9bf29f6] initial data
 1 file changed, 1 insertion(+)
 create mode 100644 text.txt

# modify the file(s)
$ echo "modified" > text.txt 
# create untracked files
$ touch untracked

# stash modified
$ git stash push --keep-index
Saved working directory and index state WIP on master: 9bf29f6 initial data

# add all remaining untracked ones to index
git add .

# stash the index (of untracked files)
$ git stash
Saved working directory and index state WIP on master: 9bf29f6 initial data

# state of the stash
$ git stash list
stash@{0}: WIP on master: 9bf29f6 initial data
stash@{1}: WIP on master: 9bf29f6 initial data

# pop the first inserted one stash item (all modified only)
$ git stash pop stash@{1}
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   text.txt

no changes added to commit (use "git add" and/or "git commit -a")
Dropped stash@{1} (0dc91d25f9f3fcb63080b5413a86daf5eff1e527)

# add all modified to index
$ git add .

# commit them
$ git commit -m "these are modified only"
[master e038574] these are modified only
 1 file changed, 1 insertion(+), 1 deletion(-)

# restore unmodified/untracked files
$ git stash pop
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    new file:   untracked

Dropped refs/stash@{0} (608a98bf1208cad6d231025d68e9dc6450de98ed)

# remove untracked from index
$ git reset HEAD
$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
    untracked

nothing added to commit but untracked files present (use "git add" to track)
Peter Badida
  • 11,310
  • 10
  • 44
  • 90