I would say that 95% of developers who use git, mainly use the CLI. Its a hurdle you need to just work hard enough until you get over it. And do lots of Googling. I've been using Git professionally for a while now and I still have to google basic commands. My work monitor is covered in little stickies for Git things that I use a lot.
Samort7's Super Simple Git Tutorial
Installation
Download and install git from https://git-scm.com/ and make sure you select the option for adding git to your PATH (so your computer knows the location of git and you can use the git command in your console).
Initial Setup
When I learned Git, I started extremely simple. I created a folder called myTest on my desktop and put one file in it called test.txt. It looked like this:
AAAA
BBBB
CCCC
I then did the following steps (this is Linux, so adjust for Windows if needed):
$ cd ~/Desktop/myTest
$ git init
This marks the folder as a git "repository." A repository (or "repo") is just a folder that is tracked by Git and responds to Git commands. You'll know it's a repo because there will now be a .git sub-folder in there alongside your test.txt file.
Adding to Staging
$ git add ./test.txt
This adds my file to staging. Staging is just a preparation area where you prepare all your files before you make an official "commit." Think of a commit as permanently recording in your repo's history what changes you have made to your files. When you commit, whatever changes were staged will now be recorded in the history of your repository forever (there are ways to remove commits but its difficult and generally discouraged.)
Making a Commit
$ git commit -m "Created a file. It's my first commit!"
This commits the file with a message explaining the commit.
At this point you now have a local repository. Don't even worry about Github or pushing to Github at this point. Keeping things local makes life a lot easier when learning the basics. That means you don't have to worry about git push, git fetch, or git pull.
Changing Stuff & A Second Commit
Cool, so next I made a change to test.txt:
AAAX
BBBB
CCCC
And then I committed those changes:
$ git status
This shows me the current status of my repo. I can see very clearly that something has changed.
$ git add ./test.txt
$ git status
Ok, so now I can see I have a file added to the staging area, but it's not committed yet. Let's change that!
$ git commit -m "Changed first line!"
$ git status
Now I can see that there are no changes left! Nothing to commit! Cool!
Changing Stuff Again but Fancier!
Now change the second line, but don't commit anything yet.
AAAX
BBBX
CCCC
If you want to see the differences between your current changed version and the previous version, you may have heard about git diff. I hate git diff. I find it incredibly hard to read. But guess what? There's an even better tool built into Git! Run this command:
$ git difftool
A cool diff-viewing tool should launch showing you changes in a much easier to read way! How cool is that?
Ok, anyway, when you're done checking that tool out, you can close it and make your commit.
$ git commit -m "Change second line"
Time-travelling with Git
If you've followed along, you should now have a repo with three different versions in it. Here's where I show you some really cool fucking shit.
Run this command. Don't worry what it means. The result is what is important:
$ git log --oneline --decorate --graph --all
If you've done everything correct, you should see a neat graph explaining the history of your local repository. Pretty sweet, huh? Now, lets say that you fucked up big and you need to go back to an older version of your file, say, the first initial version you made. That's easy to do.
You should see on the graph some weird number like this d8329f (it won't match exactly, but that's fine). If you want to go the version of your file at that point, all you need to do is:
$ git checkout d8329f
This will reset your entire folder to the state it was at when you made that commit. If you open test.txt and look at it now, you should see that the first line is back to AAAA again.
If you do that git log --oneline --decorate --graph --all command again, you should see that your HEAD has moved down to the first version of your file. That tells you something: HEAD is what version of the code you are currently looking at.
If you run git status again, you should also see the word master. That's the name of the "branch" you are on. It's the default name of a git repository there are ways to change it if you want. Better to just leave it as master though because its a convention that everyone uses.
Back to the Future
Anyway, if you want to go back to the latest version of your current branch, all you need to do is:
$ git checkout master
Run git log --oneline --decorate --graph --all again, and you should see your HEAD is back at the top again. Open the test.txt file and you should see all your changes are back too!
Branches and Merges
What happens if I check out an old commit and decide to make some new commits on top of it? Well, that is when we need to create a branch.
You do this with:
$ git checkout -b myNewBranchName
You can then make changes and make commits to your heart's content.
You can see all of your current local branches with git branch. A * indicates the branch you are currently on.
If, after making some commits, you do git log --oneline --decorate --graph --all again, you will be able to see your branch extending off of your main master branch. In order to get your branch and your master branch to connect again, you have to do a merge.
During a merge, Git compares the files in two different branches to see if they both change the same code or not. If they don't, then poof! You are back to a single master branch. However, if both branches have, let's say, changed the same line in the same file to two different things, you have what is called a conflict.
Git will actually modify the file to include both versions with some weird text that looks like this: <<<<<<<<<<. You then have to resolve the conflict, by editing the file to contain only the code that you want to keep.
An example of what a conflicted file looks like, and an explanation of how to read it can be found here.
A Note on Remotes and the word Origin
One thing that tripped me up forever learning Git. When you see the word "remote", just remember that it means an alias (aka a nickname) for a branch.
i.e. if I run this command inside my myTest folder:
$ git remote add origin git@github.com:myGithubName/myRepoName.git
All I am doing is saying: "Hey Git on my local machine! Whenever I use the word origin, I am really talking about this repository on my Github account. Don't forget that! Thanks!"
So when you do something later like git push origin master, what you are actually doing is saying "Hey Git! I want to save all of the commits of my current working branch to the master branch of 'origin'. You do remember what 'origin' was, don't you?"
(This is different from git push origin which will save all of the commits on ALL of your local branches to the matching branches on origin.)
And Git says "Oh right! I remember! You told me that 'origin' was such-and-such repository on your Github account! I will save your work (and your work history) there!"
And you say "Right! Thanks Git! Let's have grab a beer later!"
The thing to remember is you don't have to call your remote "origin". It's just a nickname. It could be "MyDevGitHubRepo" for all I care. What this allows you to do is to have more than one repo you can push to. For example, you could have one remote at github and another remote at bitbucket. So you could do:
$ git push MyDevGitHubRepo master
$ git push MyProdBitBucketRepo master
Dealing with Repos on a Server
Let's say that you have two computers you work at. Computer A and Computer B. Both are editing the same codebase stored on Github (or Gitlab, or even a personal server). If computer A makes a change and pushes it to the server, I believe your question is "How does computer B know about the change that now exists on the server?" The answer is that computer B needs to do a git fetch to get the latest changes. After doing a git fetch you will see how far "behind" your code is from the github repo you are linked to.
So you find out the code has changed and your code is behind. What do you do in this situation? Well, before you are allowed to git push your code to the server, you need to get the latest code changes and merge them into your local branch. You do this by first getting the latest changes (git fetch as explained previously) and then by doing a git merge and finally resolving conflicts as usual. Only then can you do a git push of your changes.
Because we do git fetch and then git merge so often, there is a convenience method that does both for us: git pull.
Further Reading
Ok, that's enough for basics now. Try learning the difference between a merge and a rebase, cloning a remote repo, and how to link a local repo to a github repo. It's also really important to learn about the .gitignore file and the .gitconfig file.
To do this, just Google and read the Stack Overflow results. Honestly, I find them a lot easier to understand than the official Git manual pages.
Hope this helps! Good luck! Keep at it, and don't fight the command line! It's your friend :)
Also, be sure to read my ADVANCED TIPS & TRICKS comment below!
Ran out of space in my original comment so...
Samort7's Super Cool Tricks for Advanced Git Users
Ok, this is totally not necessary, but I gotta mention them because I friggin love them. Some are linux only, so beware!
Aliases in .gitconfig
So if you edit the .gitconfig file in your home directory (should be at ~/.gitconfig) you can add all sorts of neat stuff. Some of my favorite things include aliases (aka shortcuts) for stuff I use all the time. For example, if you add this line:
[alias]
l = log --oneline --decorate --graph --all
Now you can just type $ git l to get that neat little tree to show up, instead of having to type the whole line.
More readable git diff
When you start getting use to using git diff a lot, you may find that its a bit hard to read. I would suggest trying out Diff-So-Fancy which makes it a lot easier to read.
Here's quick installation instructions:
# Requires diff-so-fancy
$ sudo wget -P /usr/bin https://raw.githubusercontent.com/so-fancy/diff-so-fancy/master/third_party/build_fatpack/diff-so-fancy
# Set permissions of the file
$ sudo chmod 777 /usr/bin/diff-so-fancy
# Add it to your git config
$ git config --global core.pager "/usr/bin/diff-so-fancy | less --tabs=4 -RFX"
Then, add these lines to your .gitconfig for a really colorful readable git diff:
[core]
pager = diff-so-fancy | less --tabs=4 -RFX
[color "diff"]
meta = yellow
frag = magenta bold
commit = yellow bold
old = red
new = green
whitespace = red reverse
[diff-so-fancy]
markEmptyLines = false
Linux prompt that shows you git status:
Add this line to your ~/.bash_profile or ~/.bashrc:
export PS1='\[\e[01;30m\]\D{%r}`if [ $? = 0 ]; then echo "\[\e[32m\] ✔ "; else echo "\[\e[31m\] ✘ "; fi`\[\e[00;37m\]\u\[\e[01;37m\]:`[[ $(git status 2> /dev/null) =~ Changes\ to\ be\ committed: ]] && echo "\[\e[33m\]" || echo "\[\e[31m\]"``[[ ! $(git status 2> /dev/null) =~ nothing\ to\ commit,\ working\ .+\ clean ]] || echo "\[\e[32m\]"`$(__git_ps1 "(%s)\[\e[00m\]")\[\e[01;34m\]\w\[\e[00m\]\$ '
Your command prompt will now show you if your last command failed or succeeded, what branch you are on (when you are in a git repo) and the color will indicate if you have things uncommited, staged, or nothing to commit! Soooo useful!
How to select the files you want to stage INTERACTIVELY
Let's say you are trying to stage a commit where you modified a bunch of files but not all of them. Typically, you would have to do something like this:
git add file1
git add file2
git add file5
git add file7
Good LORD is that tedious. Fortunately, there is an INTERACTIVE TOOL to make this easier! All you need to do is:
git add -i
I use this ALL THE TIME.
0
You can add this document to your study collection(s)
Sign in Available only to authorized usersYou can add this document to your saved list
Sign in Available only to authorized users(For complaints, use another form )