The complete guide to Git - part 1 03-03-2017, 11:51 PM
#1
Git - sometimes expanded as "goddamn idiotic truckload of shit" by its original creator Linus Torvalds - is much better and more useful than that title makes it seem. Git is (officially) what's known as a distributed RC (revision control) system, though many refer to it and other similar programs as VC (version control) systems. The common use case for programs like Git, Subversion, and Mercurial is backing up code and hosting it on sites like GitHub or on your own server using something like Gogs. This is all well and good, but the platform offers so much more than just those features.
In this part, we'll be going over installation, configuration, Initialization, basic repository control, and commits. Combined, this information is enough to create a genuine Git environment and revert changes when you inevitably fuck something up.
Installing Git can be done a few ways: building from source (which I won't go over), through a package manager, or through the msysGit installer on Windows.
Package managers
Git is in the official repositories of every package manager I can think of. If you have apt (Debian), yum (RHEL), pacman (Arch), or even brew or macports (OSX), you can install Git as you would any other package.
Windows binary
If you're on Windows and thus don't have access to the above package managers, you can install Git via the msysGit binary located here.
The minimal configuration options are your name and email. You can set them with the following commands.
To actually use git, you need an ssh key. If you've already set one up for other reasons, you can skip this step. To generate a key, you need the openssh package (installed the same way as above, comes with the windows installer). After ssh is installed, run the following command and use the default options. Git will look for your key automatically, so you don't need to do anything further on your computer. You may want to add your ssh key to your github/gitlab/whatever account (quick guide) so you don't need to enter your password every time you push/pull to remote repositories (which will be discussed later).
To get a Git repository running, you can either clone an existing one and work off of that or initialize your own to start from scratch.
To clone repos, you can use either of the commands below. To avoid confusion, the second uses an ssh connection syntax, meaning you're ssh-ing into the "git" user on github.com and accessing the path after the colon. For future reference, you can use either for any urls in Git commands.
Note: if you're not cloning a repository to base your project on (often called "forking" on GitHub) (e.g. building something from source or using files from it), use the "--depth 1" flag before the url to only get the latest commit. Since you only need the latest version of the file or files you're after, there's no sense in downloading the entire commit history. For example, adding the depth flag when cloning jQuery's production repo produces a 2.2 MB directory, while cloning the entire repo is 23 MB (roughly 1000% of the size). I personally think this flag should be the default (which it's not) or there should be config option for it (which there isn't), but c'est la vie.
To initialize your own repo, enter your project directory (or create one if there's no project yet) and run "git init". You should get something similar to the message below.
For git to track anything, you need to "stage" your files. After you've gotten to a point in your project that you would like to be a restore point, you must track any previously untracked files (i.e. everything that wasn't the same your previous commit (modifications, additions, etc...), so all files if you haven't committed yet) before you can commit. You can track these files manually with "git add <file> [files...]" or you can track everything with "git add ." or "git add *". If there are no new files (i.e. files were only modified, moved, and deleted), you can skip staging with "git add" and use the "-a" flag in your commit, which stages previously tracked files automatically. Here's an abbreviated example using one of my projects.
A helpful thing you can do as demonstrated above is list the status of the repository with "git status" to see what's going on and what needs to be done before committing. A neat trick is using the "-s"/"--short" and/or "-b"/"--branch" flags for parsing with scripts (see here for all status codes).
Additionally, you can move (also used to rename) and delete files within Git, and both operations are automatically recorded (note that "deleted: Cargo.lock" was already recorded before I staged anything else in the first example). See below for syntax.
After staging changes, you need to commit them for Git to establish a restore point. I recommend adding the "-m" or "--message" flag with a commit message, otherwise you'll be brought to vim to enter one, which is a bit of a pain in the ass. As mentioned earlier, if you don't need to stage any new files, you can add the "-a" or "--all" flag to your command. Here's an example commit command wherein I modified a bunch of stuff, added a file called vga_buffer.rs, and deleted a file called Cargo.lock:
Resets
I thought I should put a subsection on resets under commits since the two go hand-in-hand. If you've royally fucked up your staging area somehow and want to revert to how it was before you messed with it (but still keep file changes on disk), you can run "git reset HEAD".
You can also reset to previous commits - effectively deleting the ones succeeding it - if you committed something incorrect and want to revise it. Keep in mind you'll need to restage any modifications. The syntax for this is either "<object>~<n>" (where object is a Git object - usually HEAD - and n is the number of commits you're reverting) or a commit hash (which can be found via "git log". You don't need the whole hash, just the first 6 or so characters).
Note: only use this method of revision if you haven't pushed the commit(s) you're deleting to a remote. Things get very screwed up and annoying to fix. I'll be going over hotfixes in a later part.
If you want to perform any reversions to both staging and on disk, add the "--hard" flag before HEAD. This will delete the commit(s) you're reverting (if any), reset your staging area, and change all modified files back to what they were at the time of committing.
In this part, we'll be going over installation, configuration, Initialization, basic repository control, and commits. Combined, this information is enough to create a genuine Git environment and revert changes when you inevitably fuck something up.
Installation
Installing Git can be done a few ways: building from source (which I won't go over), through a package manager, or through the msysGit installer on Windows.
Package managers
Git is in the official repositories of every package manager I can think of. If you have apt (Debian), yum (RHEL), pacman (Arch), or even brew or macports (OSX), you can install Git as you would any other package.
Code:
# apt (Debian)
sudo apt-get install git
# yum (RHEL)
sudo yum install git
# pacman (Arch)
sudo pacman -S git
# macports (OSX)
sudo port install git +svn +doc +bash_completion +gitweb
# brew (OSX)
brew install gitWindows binary
If you're on Windows and thus don't have access to the above package managers, you can install Git via the msysGit binary located here.
Configuration
The minimal configuration options are your name and email. You can set them with the following commands.
Code:
git config --global user.name "<your name>"
git config --global user.email "<your email>"To actually use git, you need an ssh key. If you've already set one up for other reasons, you can skip this step. To generate a key, you need the openssh package (installed the same way as above, comes with the windows installer). After ssh is installed, run the following command and use the default options. Git will look for your key automatically, so you don't need to do anything further on your computer. You may want to add your ssh key to your github/gitlab/whatever account (quick guide) so you don't need to enter your password every time you push/pull to remote repositories (which will be discussed later).
Code:
ssh-keygen -t rsaInitialization
To get a Git repository running, you can either clone an existing one and work off of that or initialize your own to start from scratch.
To clone repos, you can use either of the commands below. To avoid confusion, the second uses an ssh connection syntax, meaning you're ssh-ing into the "git" user on github.com and accessing the path after the colon. For future reference, you can use either for any urls in Git commands.
Note: if you're not cloning a repository to base your project on (often called "forking" on GitHub) (e.g. building something from source or using files from it), use the "--depth 1" flag before the url to only get the latest commit. Since you only need the latest version of the file or files you're after, there's no sense in downloading the entire commit history. For example, adding the depth flag when cloning jQuery's production repo produces a 2.2 MB directory, while cloning the entire repo is 23 MB (roughly 1000% of the size). I personally think this flag should be the default (which it's not) or there should be config option for it (which there isn't), but c'est la vie.
Code:
git clone https://github.com/<user or org>/<repo>[.git]
git clone git@github.com:<user or org>/<repo>[.git]To initialize your own repo, enter your project directory (or create one if there's no project yet) and run "git init". You should get something similar to the message below.
Code:
$ mkdir example && cd example
$ git init
Initialized empty Git repository in /home/inori/Desktop/example/.git/Basic repo control
For git to track anything, you need to "stage" your files. After you've gotten to a point in your project that you would like to be a restore point, you must track any previously untracked files (i.e. everything that wasn't the same your previous commit (modifications, additions, etc...), so all files if you haven't committed yet) before you can commit. You can track these files manually with "git add <file> [files...]" or you can track everything with "git add ." or "git add *". If there are no new files (i.e. files were only modified, moved, and deleted), you can skip staging with "git add" and use the "-a" flag in your commit, which stages previously tracked files automatically. Here's an abbreviated example using one of my projects.
Code:
$ git status
Changes to be committed:
deleted: Cargo.lock
Changes not staged for commit:
modified: .gitignore
modified: Cargo.toml
modified: Makefile
modified: src/arch/x86_64/grub.cfg
modified: src/arch/x86_64/long_mode_init.asm
modified: src/lib.rs
$ git add Makefile src/lib.rs
$ git status
Changes to be committed:
deleted: Cargo.lock
modified: Makefile
modified: src/lib.rs
Changes not staged for commit:
modified: .gitignore
modified: Cargo.toml
modified: src/arch/x86_64/grub.cfg
modified: src/arch/x86_64/long_mode_init.asm
$ git add .
$ git status
Changes to be committed:
modified: .gitignore
deleted: Cargo.lock
modified: Cargo.toml
modified: Makefile
modified: src/arch/x86_64/grub.cfg
modified: src/arch/x86_64/long_mode_init.asm
modified: src/lib.rsA helpful thing you can do as demonstrated above is list the status of the repository with "git status" to see what's going on and what needs to be done before committing. A neat trick is using the "-s"/"--short" and/or "-b"/"--branch" flags for parsing with scripts (see here for all status codes).
Code:
$ git status -s
?? untracked-file
RM old-name -> new-name
$ git status -sb
## master
?? untracked-file
RM old-name -> new-nameAdditionally, you can move (also used to rename) and delete files within Git, and both operations are automatically recorded (note that "deleted: Cargo.lock" was already recorded before I staged anything else in the first example). See below for syntax.
Code:
# move files
$ git mv <source> <destination>
# remove files from staging but keep on disk
$ git rm --cache <source>
# remove from staging + delete from disk
$ git rm -f <source>Committing changes
After staging changes, you need to commit them for Git to establish a restore point. I recommend adding the "-m" or "--message" flag with a commit message, otherwise you'll be brought to vim to enter one, which is a bit of a pain in the ass. As mentioned earlier, if you don't need to stage any new files, you can add the "-a" or "--all" flag to your command. Here's an example commit command wherein I modified a bunch of stuff, added a file called vga_buffer.rs, and deleted a file called Cargo.lock:
Code:
$ git add src/vga_buffer.rs
$ git commit -am "Add VGA buffer"
[master 5ef744c] Add VGA buffer
8 files changed, 179 insertions(+), 46 deletions(-)
delete mode 100644 Cargo.lock
rewrite src/lib.rs (85%)
create mode 100644 src/vga_buffer.rsResets
I thought I should put a subsection on resets under commits since the two go hand-in-hand. If you've royally fucked up your staging area somehow and want to revert to how it was before you messed with it (but still keep file changes on disk), you can run "git reset HEAD".
Code:
# remove all files from staging
$ git rm -r --cached .
$ git status -s
D .gitignore
D Cargo.toml
D LICENSE
D Makefile
D README.md
D src/arch/x86_64/boot.asm
D src/arch/x86_64/grub.cfg
D src/arch/x86_64/linker.ld
D src/arch/x86_64/long_mode_init.asm
D src/arch/x86_64/multiboot_header.asm
D src/lib.rs
D src/vga_buffer.rs
?? .gitignore
?? Cargo.toml
?? LICENSE
?? Makefile
?? README.md
?? src/
# reset staging
$ git reset HEAD
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working tree cleanYou can also reset to previous commits - effectively deleting the ones succeeding it - if you committed something incorrect and want to revise it. Keep in mind you'll need to restage any modifications. The syntax for this is either "<object>~<n>" (where object is a Git object - usually HEAD - and n is the number of commits you're reverting) or a commit hash (which can be found via "git log". You don't need the whole hash, just the first 6 or so characters).
Note: only use this method of revision if you haven't pushed the commit(s) you're deleting to a remote. Things get very screwed up and annoying to fix. I'll be going over hotfixes in a later part.
Code:
# add a readme file to staging
$ git add readme.md
# commit changes
$ git commit -m "Add readme"
# "shit, I missed something"
# reset HEAD to previous commit
$ git reset HEAD~1
# edit readme
$ nano readme.md
# re-stage file
$ git add readme.md
# re-commit changes
$ git commit -m "Add readme"If you want to perform any reversions to both staging and on disk, add the "--hard" flag before HEAD. This will delete the commit(s) you're reverting (if any), reset your staging area, and change all modified files back to what they were at the time of committing.
Code:
$ ls
test1.txt test2.txt
$ echo hello > test3.txt
$ git add test3.txt
$ git commit -m "Add test3.txt"
[master dd1c0e3] Add test3.txt
1 file changed, 1 insertion(+)
create mode 100644 test3.txt
$ ls
test1.txt test2.txt test3.txt
$ git reset --hard HEAD~1
HEAD is now at 3023cc1 Initial commit
$ ls
test1.txt test2.txtIt's often the outcasts, the iconoclasts ... those who have the least to lose because they
don't have much in the first place, who feel the new currents and ride them the farthest.
don't have much in the first place, who feel the new currents and ride them the farthest.

















![[+]](https://sinister.li/images/modern/collapse_collapsed.png)


