The great thing about git is there’s so little you need to know! Without further ado, let’s begin with the most important commands.
First, I’m working with a previous project of mine located here:
[user@lj src]$ pwd
/home/lj/projects/java/spaceInvaders/src
DEEP DIVE
To create a local repository, simply run:
[user@lj src]$ git init
Initialized empty Git repository in
↪/home/lj/projects/java/spaceInvaders/src/.git/
To add all source files recursively to git’s index, run:
[user@lj src]$ git add .
To push these indexed files to the local repository, run:
[user@lj src]$ git commit
You’ll see a screen containing information about the commit, which allows you to leave a description of the commit:
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
#
Initial commit
Changes to be committed:
new file: engine/collisionChecker.java new file: engine/direction.java
new file: engine/gameEngine.java new file: engine/gameObjects.java new file: engine/level.java
new file: engine/main.java
new file: engine/mathVector.java new file: graphics/drawer.java new file: sprites/baseSprite.java
DEEP DIVE
new file: sprites/boss.java new file: sprites/enemy.java new file: sprites/healthBar.java new file: sprites/menu/menuItem.java
new file: sprites/menu/menuItemExclusiveMoveOnInput.java new file: sprites/menu/menuItemLevelDecrease.java
new file: sprites/menu/menuItemLevelIncrease.java
new file: sprites/menu/menuItemMovementDirections.java new file: sprites/menu/menuItemProjectileLimit.java new file: sprites/menu/menuItemStartGame.java
new file: sprites/pickup/fireRateBoost.java
DEEP DIVE
new file: sprites/boss.java new file: sprites/enemy.java new file: sprites/healthBar.java new file: sprites/menu/menuItem.java
new file: sprites/menu/menuItemExclusiveMoveOnInput.java new file: sprites/menu/menuItemLevelDecrease.java
new file: sprites/menu/menuItemLevelIncrease.java
new file: sprites/menu/menuItemMovementDirections.java new file: sprites/menu/menuItemProjectileLimit.java new file: sprites/menu/menuItemStartGame.java
new file: sprites/pickup/fireRateBoost.java
27 files changed, 2557 insertions(+)
create mode 100755 engine/collisionChecker.java
DEEP DIVE
create mode 100755 sprites/menu/menuItemLevelDecrease.java create mode 100755 sprites/menu/menuItemLevelIncrease.java create mode 100755 sprites/menu/menuItemMovementDirections.java create mode 100755 sprites/menu/menuItemProjectileLimit.java create mode 100755 sprites/menu/menuItemStartGame.java
create mode 100755 sprites/pickup/fireRateBoost.java create mode 100755 sprites/pickup/pickup.java
create mode 100755 sprites/pickup/shield.java
create mode 100755 sprites/pickup/shieldPickup.java create mode 100755 sprites/pickup/speedBoost.java create mode 100755 sprites/player.java
create mode 100755 sprites/projectile.java create mode 100755 sprites/wall.java
Files are removed from the index in the same *NIX style:
[user@lj src]$ git rm -r .
rm 'engine/collisionChecker.java' rm 'engine/direction.java'
rm 'engine/gameEngine.java'
... SNIP ...
To compare my local index with the repository, I use git diff (note: the row of hyphens at the end of most lines was trimmed for readability):
[user@lj src]$ git diff --cached --stat
engine/collisionChecker.java | 281 --- ...
engine/direction.java | 14
engine/gameEngine.java | 504 --- ...
engine/gameObjects.java | 61 --- ...
engine/level.java | 134 --- ...
engine/main.java | 51 --- ...
DEEP DIVE
sprites/menu/menuItemExclusiveMoveOnInput.java | 31 --- ...
sprites/menu/menuItemLevelDecrease.java | 28 --- ...
sprites/menu/menuItemLevelIncrease.java | 27 --- ...
sprites/menu/menuItemMovementDirections.java | 30 --- ...
sprites/menu/menuItemProjectileLimit.java | 31 --- ...
sprites/menu/menuItemStartGame.java | 33 --- ...
27 files changed, 2557 deletions(-)
When used without the cached option, only changes that have been made without being added to the index will be displayed. The stat option provides a quick table instead of the standard line-by-line review provided through the less command without it. This is often useful when looking for a summary of many files instead of analyzing small changes.
git status provides a more verbose output similar to diff:
[user@lj src]$ git status On branch master
DEEP DIVE
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
deleted: engine/collisionChecker.java deleted: engine/direction.java
deleted: engine/gameEngine.java ... SNIP ...
Branches are an essential part of git, and understanding them is paramount to grasping how git truly operates. Each branch is a different development path, which is to say that all branches are independent of one another. To explain this better, let’s look at an example.
All projects start with the “master” branch. You can view the current branches with:
[user@lj src]$ git branch -a
* master
New branches are used to develop features that then can be merged back into the master branch. This way, different modules can remain separate until they are stable and ready to merge with the master branch, from which all other branches should derive. In this way, the master branch is more like a tree trunk than a branch. Creating a new branch often is referred to as “forking” the development tree, splitting the linear development into two before merging the branches again once development on the forked branch is complete.
To create a new branch, with all the data of the current branch, use:
[user@lj src]$ git checkout -b development Switched to a new branch 'development'
checkout is used to finalize all operations on the current branch before detaching
DEEP DIVE
from it. The -b switch creates a new branch from the current branch. In this instance, I have created a development branch that will contain “hot” or unstable code.
Next, rename the master branch to “stable”:
[user@lj src]$ git branch -m master stable
Now that you have your two branches set up, let’s compare them to ensure that the development branch has been populated with the stable branch’s data:
[user@lj src]$ git diff --stat development stable [user@lj src]$
Since diff hasn’t returned anything, you know they contain exactly the same data.
Now that you’ve got your two branches set up, let’s begin making changes on the development branch:
[user@lj src]$ git diff --cached
diff --git a/engine/main.java b/engine/main.java index 38577b5..5900d80 100755
--- a/engine/main.java +++ b/engine/main.java
@@ -11,6 +11,8 @@ import graphics.drawer;
public class main {
+ // WHEN CAN I GO BACK TO C!?!?!?
+
/*
* Class: main * Author: Patrick
DEEP DIVE
And commit them to the branch:
[user@lj src]$ git commit
[development e1f13bd] Changes to be committed: modified:
↪engine/main.java
1 file changed, 2 insertions(+)
After committing the change, you’re given a unique identifier—“e1f13bd” in this case.
It’s used to refer to this commit; however, it’s pretty hard for feeble human minds to remember something like that, so let’s tag it with something more memorable.
First, find and tag the initial commit:
[user@lj src]$ git log
commit e1f13bde0bbe3d64f563f1abb30d4393dd9bd8d9 Author: user <[email protected]>
Date: Wed Jun 6 15:51:18 2018 +0100
Changes to be committed:
modified: engine/main.java
commit 4cf52187829c935dac40ad4b65f02c9fb6dab7ba Author: user <[email protected]>
Date: Tue Jun 5 21:31:14 2018 +0100
Initial commit
Changes to be committed:
new file: engine/collisionChecker.java new file: engine/direction.java
new file: engine/gameEngine.java ... SNIP ...
DEEP DIVE
[user@lj src]$ git tag v0.1 4cf52187829c935dac40ad4b65f02c9fb
↪6dab7ba
[user@lj src]$ git tag v0.11 e1f13bd
Now that the two commits have been tagged with a version number, they’re much easier to remember and compare:
[user@lj src]$ git diff --stat v0.1 v0.11 engine/main.java | 2 ++
1 file changed, 2 insertions(+)
After testing and ensuring that the development branch is stable, you should update the stable branch to the current development branch:
[user@lj src]$ git checkout stable Switched to branch 'stable'
[user@lj src]$ git merge development Updating 4cf5218..e1f13bd
Fast-forward
engine/main.java | 2 ++
1 file changed, 2 insertions(+)
As you can see below, both branches still exist and contain the same data:
[user@lj src]$ git branch -a development
* stable
[user@lj src]$ git diff --stat stable development
If at any time you want to roll back, use git revert to revert a commit and undo any changes it made:
DEEP DIVE
[user@lj src]$ git revert v0.11
[stable 199169f] Revert " Changes to be committed:"
1 file changed, 2 deletions(-)
[user@lj src]$ git diff --stat stable development engine/main.java | 2 ++
1 file changed, 2 insertions(+)
This is all you need to know to get started and become proficient in using git for personal use. All git repos operate the same way; however, working with remote repositories owned by others brings its own caveats. Read on.