Tutorial Git Commit

From HaFrWiki
Jump to: navigation, search

Shows the git commit -all command in detail and evaluates the git rm.
The example is a written example from Version Control with Git [1].


In Git, a commit is used to record changes to a repository. At face value, a Git commit seems no different from a commit or check in found in other VCS.
Under the hood, however, a Git commit operates in a unique way.
When a commit occurs, Git records a snapshot of the index and places that snapshot in the object store.


Set up the repo and initializes the data.

<syntaxhighlight lang="bash">

  1. Setup test repository

$ mkdir /test/tutgitcommitall $ cd /test/tutgitcommitall $ git init Initialized empty Git repository in /Test/tutgitcommitall/.git/

$ echo something >> ready $ echo something else >> notyet $ git add ready notyet $ git commit -m "Setup" [master (root-commit) 5105eaf] Setup

2 files changed, 2 insertions(+)
create mode 100644 notyet
create mode 100644 ready


Making changes

Makes the necessary modification and creates different stages before doing a commit.

<syntaxhighlight lang="bash">

  1. Modify file "ready" and "git add" it to the index

$ nano ready ... $ git add ready

  1. Modify file "notyet", leaving it unstaged.

$ nano notyet ...

  1. Add a new file in a subdirectory, but don't add it.

$ mkdir subdir $ echo Nope >> subdir/new

  1. Use git status to see what a regular commit (without command line options) would do:

$ git status

  1. On branch master
  2. Changes to be committed:
  3. (use "git reset HEAD <file>..." to unstage)
  4. modified: ready
  5. Changes not staged for commit:
  6. (use "git add <file>..." to update what will be committed)
  7. (use "git checkout -- <file>..." to discard changes in working directory)
  8. modified: notyet
  9. Untracked files:
  10. (use "git add <file>..." to include in what will be committed)
  11. subdir/


Git Commit

Here, the index is prepared to commit just the one file named ready, because it’s the only file that has been staged.

However, if you run git commit --all, Git recursively traverses the entire repository, stages all known, modified files and commits those.
In this case, when your editor presents the commit message template, it should indicate that the modified and known file notyet will, in fact, be committed as well: <syntaxhighlight lang="bash"> $ git commit --all ....

  1. Please enter the commit message for your changes. Lines starting
  2. with '#' will be ignored, and an empty message aborts the commit.
  3. On branch master
  4. Changes to be committed:
  5. modified: notyet
  6. modified: ready
  7. Untracked files:
  8. subdir/

$ git status On branch master Untracked files:

 (use "git add <file>..." to include in what will be committed)


nothing added to commit but untracked files present (use "git add" to track) </syntaxhighlight>

Finally, because the directory named subdir/ is new and no file name or path within is tracked, not even the --all option causes it to be committed.
While Git recursively traverses the repository looking for modified and removed files, the completely new file subdir/ directory and all of its files do not become part of the commit.

Git rm

The command git rm is, naturally the inverse of git add.
It removes a file from both the repository and the working directory.
However, because removing a file tends to be more problematic (if something goes wrong) than adding a file, Git treats the removal of a file with a bit more care.

Git will remove a file only from the index or from the index and working directory simultaneously.
Git will not remove a file just from the working directory; the regular rm command may be used for that purpose.

Removing a file from your directory and the index does not remove the file’s existing history from the repository.
Any versions of the file that are part of its history already committed in the repository remain in the object store and retain that history.

Introducing an “accidental” additional file that shouldn’t be staged and see how to remove it. <syntaxhighlight lang="bash">

  1. Creation of the oops file.

$ echo "Random stuff" > oops

  1. Can't "git rm" files Git considers "other"
  2. This should be just "rm oops"

$ git rm oops fatal: pathspec 'oops' did not match any files </syntaxhighlight>

Because git rm is also an operation on the index, the command won’t work on a file that hasn’t been previously added to the repository or index.
Git must first be aware of a file.
So let’s accidentally stage the oops file: <syntaxhighlight lang="bash">

  1. Accidentally stage "oops" file

$ git add oops $ git status

  1. Changes to be committed:
  2. (use "git rm --cached <file>..." to unstage)

$ git rm --cached oops rm 'oops'

$ git ls-files --stage 100644 ce60e61fb398bff486f566f8cc0e518fdb039a16 0 notyet 100644 99ce413c4d3493bfcf4afb777a3ee07914b9abaa 0 ready 100644 c9e302a78b5660de810c6a0161c8592ceed1ea5c 0 subdir/new </syntaxhighlight>

Whereas git rm --cached removes the file from the index and leaves it in the working directory, git rm removes the file from both the index and the working directory.

<syntaxhighlight lang="bash">

  1. Creating some data

echo "Some data" >> data

  1. Adding all the files

$ git add data $ git commit -m "Add some files" [master ca51122] Some files

1 file changed, 1 insertion(+)
create mode 100644 data
  1. Now accidental remove data

$ git rm data rm 'data'

$ git status

  1. On branch master
  2. Changes to be committed:
  3. (use "git reset HEAD <file>..." to unstage)
  4. deleted: data
  5. Untracked files:
  6. (use "git add <file>..." to include in what will be committed)
  7. oops


Before Git removes a file, it checks to make sure the version of the file in the working directory matches the latest version in the current branch (the version that Git commands call the HEAD).
This verification precludes the accidental loss of any changes (due to your editing) that may have been made to the file. <syntaxhighlight lang="text"> Use git rm -f to force the removal of your file. Force is an explicit mandate and removes the file even if you have altered it since your last commit.

And in case you really meant to keep a file that you accidentally removed, simply add it back: </syntaxhighlight> <syntaxhighlight lang="bash"> $ git add data fatal: pathspec 'data' did not match any files </syntaxhighlight> Shit, Git removed the working copy. Simply recover it <syntaxhighlight lang="bash"> $ git checkout HEAD -- data $ cat data </syntaxhighlight>

See also




  1. Version Control with Git, Powerful Tools and Techniques for Collaborative Software Development, Jon Loeliger & Matthew McCullough, O'Reilly, 2012 Second Edition, isbn=9781449316389