1.2. Using Git

When you are programming, you will make mistakes. If you program long enough, these will eventually include shenanigans like accidentally deleting all of your source files. You are also likely to spend some of your time trying out things that don’t work, at the end of which you’d like to go back to the last version of your program that did work. All these problems can be solved by using a version control system.

A brief summary of git is given below. For more details, see the tutorials available at http://git-scm.com.

Whatever version control software you use, they all follow the same basic pattern:

  1. Initialize repository

    You only need to do this step once.

    If you already have a repository available on a remote server, then you can use git clone instead of git init.

  2. Work with repository

    1. Create new files

    2. Add files to repository

    3. Edit existing files

    4. Commit changes

    5. Push local changes to a remote server like GitHub for safe keeping.

    Repeat the above as often as needed.

1.2.1. Initialize a git repository

Typically you run git inside a directory that holds some project you are working on (for example, homework). Before you can do anything with git, you need to create or copy a repository, which is a hidden directory .git that records changes to your files.

In this example, we will be walking though a small empty repository.

If we choose to put it in a new directory git-demo:

$ mkdir git-demo
$ cd git-demo/
$ git init

Then we should see something like:

Initialized empty Git repository in /home/runner/WorrisomeSophisticatedCybernetics/git-demo/.git

Now let’s create a file and use git add to add it to the repository:

$ echo 'int main(int argc, char** argv) { return 0; }' > tiny.cpp
$ git add tiny.cpp

The git status command will tell us that Git knows about tiny.cpp, but hasn’t committed the changes to the repository yet:

$ git status
On branch master

Initial commit

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

  new file:   tiny.cpp

The git commit command will save the actual changes, along with a message saying what you did. For short messages, the easiest way to do this is to include the message on the command line:

$ git commit -m 'a very short c++ program'
[master (root-commit) 3a6fd19] a very short c++ program
 1 file changed, 1 insertion(+)
 create mode 100644 tiny.cpp

Without the -m argument, git runs the default editor (vim) to let you edit your commit message. If you don’t like vim, you can change the default using git config:

$ git config --global core.editor "emacs -nw"

You can see what commits made so far using git log:

$ git log
commit 3a6fd19e8ef4662744bd41a20cde9924aad918ed
Author: DaveParillo <DaveParillo@noreply.github.com>
Date:   Sat Jun 10 12:07:51 2017 -0700

    a very short c++ program

Try This!

Head on over to replit.com and use the console window in a repl and practice the steps described in this section.

You can run git commands in repl’s for any language, but in order to compile tiny.cpp, you’ll need to be in a C++ repl.

1.2.2. Editing files

Suppose I edit tiny.cpp using my favorite editor to turn it into the classic hello-world program:

#include <iostream>

int main() {
  std::cout << "Hello, world!\n";
  return 0;
}

I can see what files have changed using git status:

$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

  modified:   tiny.cpp

no changes added to commit (use "git add" and/or "git commit -a")

Notice how Git reminds me to use git commit -a to include these changes in my next commit. I can also do git add tiny.cpp to only include the changes to tiny.cpp (maybe I made changes to a different file that I want to commit separately).

If I want to know the details of the changes since my last commit, I can run git diff:

$ git diff
diff --git a/tiny.cpp b/tiny.cpp
index a9b8738..a6501a7 100644
--- a/tiny.cpp
+++ b/tiny.cpp
@@ -1 +1,6 @@
-int main(int argc, char** argv) { return 0; }
+#include <iostream>
+
+int main() {
+  std::cout << "Hello, world!\n";
+  return 0;
+}

Since I like these changes, I commit them:

$ git commit -a -m 'turn tiny into a basic hello world'
[master 170eaf0] turn tiny into a basic hello world
 1 file changed, 6 insertions(+), 1 deletion(-)

The repository now contains two commits:

$ git log | more
commit 170eaf0461a7f0f865328b73bee6d313c3dbad42
Author: DaveParillo <DaveParillo@noreply.github.com>
Date:   Sat Jun 10 12:23:55 2017 -0700

    turn tiny into a basic hello world

commit 3a6fd19e8ef4662744bd41a20cde9924aad918ed
Author: DaveParillo <DaveParillo@noreply.github.com>
Date:   Sat Jun 10 12:07:51 2017 -0700

    a very short c++ program

1.2.3. Renaming files

You can rename a file with git mv. This is just like the regular Linux mv command, except that it tells Git what you are doing. If you forget to use git mv it’s not normally a problem. Unless your changes are massive, git is usually good about figuring out when files have been moved:

$ git mv tiny.cpp hello.cpp
buffy:~/git-demo
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

  renamed:    tiny.cpp -> hello.cpp

Moving a file counts as a change. These changes don’t get written to the repository unless you do another git commit:

$ git commit -m 'give better name to hello program'
[master 7a603f4] give better name to hello program
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename tiny.cpp => hello.cpp (100%)

1.2.4. Adding and removing files

To add a file, create it and call git add:

$ cp hello.cpp goodbye.cpp
$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

  goodbye.cpp

nothing added to commit but untracked files present (use "git add" to track)
$ git add goodbye.cpp
$ git commit -m 'started to make a second program to say goodbye'
[master f41cb3a] started to make a second program to say goodbye
 1 file changed, 6 insertions(+)
 create mode 100644 goodbye.cpp

If you add many files at once, you can refer to the directory they are in. If that directory is the current directory, . is acceptable. When you specify a directory, then all of the files new or modified are added recursively from that point downward.

Git add and commit best practices

It is easy to inadvertently add files you did not mean to when adding a directory. Check what you have added using git status to ensure the files you are about to commit belong in the commit.

If you accidentally add files you did not mean to, then it is easy to “un-add” them using git revert.

General rules for adding files:

  1. Commit only source files you have created or modified.

  2. Avoid committing binary files and generated build artifacts.

To remove a file, use git rm:

$ git rm goodbye.cpp
rm 'goodbye.cpp'
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

  deleted:    goodbye.cpp

$ git commit -m 'on second thought, goodbye.cpp was a bad idea'
[master cbcf75f] on second thought, goodbye.cpp was a bad idea
 1 file changed, 6 deletions(-)
 delete mode 100644 goodbye.cpp

1.2.5. Recovering files from the repository

Nothing is ever truly deleted from the repository once checked in. If you accidentally delete something, you can recover it from the repository.:

$ ls -a
./  ../  .git/      hello.cpp

$ rm hello.cpp
$ ls -a
./  ../  .git/

# gone, but not forgotten

$ git checkout -- hello.cpp
$ ls -a
./  ../  .git/      hello.cpp

Using git checkout -- gets the most recent version out of the repository, but using the commit id, we can operate on any version:

$ git checkout 3a6f -- tiny.cpp
$ ls -a
./  ../  .git/      hello.cpp  tiny.cpp

Because tiny.cpp is not part of the current HEAD (most recent version), it is considered a new file, but the checkout did add tiny.cpp and stage it for commit:

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

  new file:   tiny.cpp

More to Explore

You have attempted of activities on this page