Git offers developers a range of features to provide powerful versioning for software projects. Git protocols come with many features and can often feel overwhelming. The
-a` flag automatically stages files that have been modified or deleted to help improve workflow efficiency.
This option does not affect any files that Git is not aware of yet, however. In this short article, we’ll take a look at setting up a basic project with git-mediated versioning and demonstrate the impact of the
-a option. Some familiarity with Git will be assumed but all steps will be outlined clearly.
-a option is used in this tutorial but can also be passed as
-all while providing the same functionality.
Quick Intro: Setting up a Git Project
To demonstrate the use of the
-a option in Git, we’ll set up a sample project, initialize Git, add our files, make some changes, add those again, and compare the differences. You will need to have Git installed to follow along. Our steps will be as follows:
- Create a sample project with a root directory, sub-directories, and sample files containing some amount of random data.
- Initialize Git in our sample project.
- Use the add, commit, and commit -a commands.
A sample project, complete with sample sub-directories containing sample files with sample content will be created using the
create_sample_project.py script (available on Github) that reflects the following structure:
. └── sample_project/ ├── sample_dir_0/ │ ├── sample_file_0_0.txt │ ├── sample_file_0_1.txt │ └── sample_file_0_2.txt └── sample_dir_1/ ├── sample_file_1_0.txt ├── sample_file_1_1.txt └── sample_file_1_2.txt
Here we see a root directory, two sub-directories, and 3 files within each subdirectory. Each sample file contains a random string of ASCII characters so that Git can detect changes later. From
Nothing special here, just 256 random ASCII characters. Next, we’ll initialize Git in our directory by running the
git init command as follows:
$ git init // output Initialized empty Git repository in /path/to/the/sample_project/.git/
git status command will provide information related to the current state of version tracking in this sample project:
$ git status On branch master No commits yet Untracked files: (use "git add <file>..." to include in what will be committed) sample_dir_0/ sample_dir_1/ nothing added to commit but untracked files present (use "git add" to track)
The last line is very telling and hints that no files are currently being tracked. If the
git commit command is run, a very similar message will be displayed. Taking the advice of Git’s messaging system, the
git add sample_dir_0/* command will notify git about all files in
sample_dir_0 and begin tracking those. Re-running the
git status command now displays the following to the terminal:
$ git status On branch master No commits yet Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: sample_dir_0/sample_file_0_0.txt new file: sample_dir_0/sample_file_0_1.txt new file: sample_dir_0/sample_file_0_2.txt Untracked files: (use "git add <file>..." to include in what will be committed) sample_dir_1/
This indicates that all files in the
sample_dir_0 directory are being tracked and that there are still un-trakced files in the
Git commit -a
-a option passed to the
commit command is described in the official git documentation as follows:
Tell the command to automatically stage files that have been modified and deleted, but new files you have not told Git about are not affected.
“Staging” a file means preparing it for a commit command and resulting
push if working with a remote repository. When the
commit command is issued, Git will add changes to any files on the “stage” which have been added via the
add command at some point. Currently, this includes all files in the
Commit Files in
commit command requires that a message is provided indicating what changes were made. Using the
-m flag will prevent the default text editor from opening (VIM in the case of most Unix-based systems.) This will add all changes from files currently added to the stage (files in
$ git commit Aborting commit due to empty commit message. $ git commit -m "initial commit" -v // output, via the -v flag [master (root-commit) d185b55] initial commit 3 files changed, 3 insertions(+) create mode 100644 sample_dir_0/sample_file_0_0.txt create mode 100644 sample_dir_0/sample_file_0_1.txt create mode 100644 sample_dir_0/sample_file_0_2.txt $ git status // output On branch master Untracked files: (use "git add <file>..." to include in what will be committed) sample_dir_1/ nothing added to commit bu untraced files present (use "git add" to track)
-v option (verbosity) outputs all files that have been updated in this commit. To followup, the
git status command indicates that there are untracked files in the
sample_dir_1 directory — because those files weren’t included in the the
git add command earlier.
Commit Files in
The simple version of using git commit -a is that it will “commit all changed files.” Unfortunately, Git does not automatically add previously untracked files via the
-a option. It will only automatically add changes from currently tracked files and deleted files that were previously tracked. Running the
git commit -a -m "second commit" && git status command will produce the following:
On branch master Untracked files: (use "git add <file>..." to include in what will be committed) sample_dir_1/ nothing added to commit but untracked files present (use "git add" to track)
In other words; files in
sample_dir_1 were not staged or committed. However, if we open the file
sample_dir_0/sample_file_0_0.txt and alter its content, the
git status command will now produce the following output:
$ git status // output 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: sample_dir_0/sample_file_0_0.txt Untracked files: (use "git add <file>..." to include in what will be committed) sample_dir_1/ no changes added to commit (use "git add" and/or "git commit -a")
This message indicates that in order to stage the changes made in
sample_file_0_0.txt one must do two things:
- Use the
- Use the
Using the -a Flag Correctly
In other words, staging and committing files is a two-step process. However, the
-a option allows this to happen in a single step as follows:
$ git commit -a -m "second commit" -v // output [master 92c024a] second commit 1 file changed, 1 insertion(+), 1 deletion(-) $ git status // output On branch master Untracked files: (use "git add <file>..." to include in what will be committed) sample_dir_1/ nothing added to commit but untracked files present (use "git add" to track)
git status command now reflects only the untracked files in the
sample_dir_1 directory. Passing the
-a flag into the
git commit command automatically stages changes to tracked files or deletions of existing tracked files and commits them in a single step.
The git commit -a command is incredibly useful when working with multiple files. Rather than having to pass in a list of all files that should be staged, sometimes across multiple directories, one can simply add any tracked files.
Keep in mind the
-a option doesn’t stage new files that aren’t currently being tracked. This is a source of confusion for many first-time git users and can result in untracked changes if not addressed. Using the git status command can provide helpful feedback to avoid such issues.
Check out our article on adding an existing project to an empty Github repo for more insights on how to better utilize Git version controlling for your projects! Also, check out our article on how to add a new directory/folder manually to a Github repo which is deceptively difficult.