[music]
What's up everyone? Welcome to another episode of c0deporn
in this episode we're gonna learn the basics git
so that you can get your projects under source control and work with and contribute
to remote repositories
Git is not new by any means but most developers that I encounter have never heard of git
or have never used it. now, since I live in the Microsoft world most of the time
I hear a lot of complaints about TFS which is Microsoft's application life cycle
management suite
which also includes source control. I personally think TFS has a lot of good
offerings
including the source control; It's very developer friendly, team friendly
inside of the enterprise, but the outside of the enterprise, it can be a little overkill for
the individual developer
and for projects with multiple disparate contributors
when I ask these teams who use TFS, what would you rather use instead
I usually hear something like, "well, subversion" or SVN
as it's also known I personally hate SVN, but when I suggest
git I usally hear the same response, well
"Git is too complicated, it's too hard to learn. I don't really understand it"
it's obviously a response from someone who has never seen git in action because git
is actually very easy to use and learn and especially considering how powerful
it is
so, why don't I go ahead and show you what I'm talking about and let's jump into the demo
so first thing is to install git. you can download the latest version of git
at git-scm.com. for this video I'm using Windows
if you're on another setup, just work on getting git installed
the usage if git will be the same no matter what system you're on
during installation
I recommend the default settings here in this screen
as far as your path settings choose whatever you like but I usually go with
use git from git bash only
for line endings I recommend sticking with the first option
and let git convert line endings for you
once the install is done it's ready to use we're gonna start off with
local repositories and learn the basics before we jump into remote stuff
so open up the git shell by right clicking on a folder
and selecting git bash. notice the git GUI option
I won't go over it here, but you should check it out once you're familiar with
the basics
git bash is a command-line environment where you can type in the commands to
control git
our first command will be git init
which will initialize a repository in the current folder
you can initialize a repository on a new folder or an existing one
so if you already have a project you can go ahead and get it under source control
all the same as from starting from scratch
after the command finishes, you'll see a new hidden folder called .git
which is where git stores everything including change sets, branches and so on
at any time you can delete this folder to destroy the repository
of course you'll lose all your change history by doing so this also means that
even though you're working under change control, it isn't a backup
unlike TFS and SVN where you're most likely checking into a remote repository
somewhere
on some server; git uses a local file base set up
and you'll need a backup manually or commit to a remote repository
but this also means you can zip this folder and send out to anyone
and they can have immediate access to the repository as long as they have git
installed
at the moment we don't have anything to put under version control so let's
create a text file
now, even though the text file exists, it isn't being tracked by git yet
we can see this by using git status to see where we stand it any given time
git status is telling us our readme file is untracked
so let's fix that by typing git add readme.txt and pressing Enter
now when we use git status
we see that our readme file is ready to commit. this is called staging
we've staged to readme file for commit
but what does it really mean? let's edit the readme file again and see what
happens
now we see that readme.txt is under both
tracked and untracked. but why? it's because when we staged a file using
the add command git staged the version of the file
as it was at that time which only had change one
so if we did a commit right now the commit would not include change two
we would need to use git add once more to stage the new changes
once we've staged our changes
we're ready to commit them to the repository we can do this using
git commit when we run git commit
we'll end up in a vim like screen because git wants us to enter a
commit message
this can be a bit confusing at first but let's run through it and I'll show you a
shortcut after
to enter commit message in this vim screen, press I
which puts you into insert mode, and then start typing your commit message
all of this text here is what git has put in beforehand automatically
to tell you what is being committed just as a kind of reminder
notice that each line starts with a hash, this means those lines will be ignored
and won't end up in your actual commit message
once you have your text in there hit the Escape key
to exit insert mode and type :wq
in lower case which will rewrite the current file and
exit causing git to finish the commit. if we use git status once more
we see that there are no more pending changes which means they were all
committed to the repository
now, if you're not vim inclined like myself
then forget about the screen let's make another change
and trying to commit
this time will provide the -m switch which will allow us to provide a
commit message
right in the command line, so we'll type in git commit
-m and then 'change 3' inside of quotes
now we don't have to bother with that vim screen if we just have a simple
commit message
at this point we have two commits in the repository
we can see the commit history using git log which will list out the commits
and their details like the author, date and commit notes
this will be very useful when you're working with other developers
let's add a new index.html to our project
now let's make another change to our readme
file
using git status we see that we have changes
to the readme file and a new untracked file. we need to stage these files and changes
which we'll do using git add but this time instead of specifying
each file name, let's stage them all at once. we do this by using
git add, followed by a period, which tells git to stage
everything. additionally we can specify wild-card pattern like
*.html which will stage only files with HTML
extensions. this is much easier than doing every file one by one
but, there will be times when we don't want to include certain files in the
repository
for example if our application generates log files we may not want those
to be tracked in source control
and using a wild-card git add command would actually add those files
so let's simulate that by creating a new log file
git status shows the log file as
untracked. if we did a git add, the log file would be staged along with the other
changes
which isn't what we want to happen. we can tell git which files to exclude
by creating a
.gitignore file which we'll use to specify files and file patterns
for git to ignore. the problem with doing this on a Windows machine is a you must type
file name
when creating new files in Windows Explorer
so a shortcut to use is, inside of the git bash
touch .gitignore which will create the file for us
afterwards you can open it in an editor. in the editor
we'll add *.log and then save the file. now when we use git status our log file
doesn't show up any longer
however, our .gitignore file does so we need to stage
and then commit the ignore file
let's move on to branching and merging. branching is something almost all version
control systems have
it allows you to work on a copy of the code in the main line without actually
affecting the main line directly
for example you would create a new branch if you're working on a bugfix
or new feature. you're working in your own branch and everyone else can continue
their work
without being affected by what you're doing but you still have all the
benefits
of source control. when you're done you would merge your changes
back into the main line. branching in git is ridiculously easy
we can create a new branch using git branch and then giving the name of your
new branch
new branch is created and we can switch to it just as easily
using git checkout followed by the branch name
everything at this point will look exactly the same, but let's make two changes
add a new file to the project and change
our readme file
then we'll stage and commit the changes
to switch back to the main branch we'll use git checkout master
master is always the name of the main branch
when we switch
back, take a look at the folder. we're missing our newly added CSS file
and our readme is missing change 5. that's because the master branch doesn't
have the changes we made in our other branch
since we're done with our
changes in the other branch, why don't we go ahead and merge them back into the master.
before we merge we need to make sure that we're on the destination branch
in this case, master is the destination and our new branch
is the source. so use git status to see which branch we're currently in
and use git checkout master to switch to the master branch if you're not already
there
then all we have to do to merge is use git merge
and then the name of the source branch. now we see our newly added CSS file in the
project folder
and the readme should now have change 5
now, while that marge was pretty smooth, most likely you're going to run into merge
conflicts
and this is the part that everybody hates. so let's cause a conflict by adding
change 6
to our readme and then committing the changes
but i'm going to show you a shortcut when using
-a in the commit command you can skip the staging step
any changes to files that are currently tracked will be automatically staged
however any new files that are untracked
won't be staged and they'll have to be added manually using git add
then we'll switch back over to our other branch
and add change 7 to the
read me and commit those changes
this time let's merge master into our new
branch
when we do that we see that there is
now merge conflict. we can also see this using git status
git was enabled to automatically to perform a merge
and now it's up to us to take care of it and resolve the conflict
examining the readme file we see some additional text
git has put information about the conflict directly in our file
the top part is the head which means the version in the current branch
the bottom part is the version of the source branch in this case
the master branch
we can easily see what we need to do to fix this so let's adjust the file
and then remove the markers that git added
once we resolved all the
conflicts we need to run to git add to mark these files as resolved
and then we commit them
you can imagine how incredibly complex this process will get in an actual project
don't worry there are better ways once you get a merge conflict you can use
git mergetool to launch a tool to help make fixing merge conflicts a lot easier
however at this point I don't have any installed or configured on
my machine. I highly recommend getting a merge tool like
tortisemerge or my personal favorite winmerge, and configure git to use it
so you don't have to try and tackle merges manually
there is plenty of documentation on configuring git for merge tools so I'm not going to
cover it here
now that we've talked about branching I wanna show you a nice feature called
stash
let's say we're in our current branch and we had a file you recall what
happened previously when we had a file to one branch
it disappeared when we switch to the other branch. but what happens if we're in a
branch
and we make changes but don't commit them? in this case
the changes remain when we switch branches as you might have guessed
this could be a big problem some point
let's say you're working on a branch and you've made a ton of changes and you're not
ready to commit them yet. but you need to switch to another branch to do a quick
bugfix or
work on something else. as we just saw your changes will persist
during the branch change which is going to be an issue so what the stash
command does
is take that dirty state of your branch including tracked modifications
and staged changes and saves it on a stack of unfinished changes that can be
reapplied at any time
so before we switch branches let's do it git status
to see that we do have changes pending
because we had a new file it isn't being tracked yet so it won't be included in the
stash
so we'll just use git add to start tracking it
now let's stash the changes using git stash
using git status shows us there's no more pending changes
when you're ready to come back and continue your work on this branch
you can reapply your changes from the stash using
git stash apply. now you're ready to continue on
okay you pretty much know the basics now so let's look at working with remote
repositories
the terms used can be a little confusing so I'll explain them and the differences as
we go
first off keep in mind that even though you're interacting with the remote
repository everything is still happening locally
you have to manually retrieve and push changes to the remote repository
we can see a list of existing remote repositories we have
using git remote at the moment we don't have any listed.
it's important to note that any remote repositories we add
will only apply to our current local repository and I'll show you what I mean
in just a bit let's go find a repository on github. I'll use a repo I created from a
.NET project called
fluent guard. first we need to get the clone URL which github provides
us
back in the git shell
we're going to clone the fluent guard repository using
git clone and providing the URL for the repository
when that's done you'll notice a new folder called fluent guard in our project
folder
cloning a repo does exactly what it implies it pulls down the entire
repository including the
entire commit history and as such, git puts everything in its own folder
if we use git remote right now we'll see nothing just like before
but let's switch over to the fluent guard folder, and use git remote
once more. now we see an entry for origin
let's use git remote with a -v
argument to have git show us the URLs. origin is the default
alias for the repo that was cloned you'll use this alias when issuing git
commands instead of the URL
now that we have the repository we can start working with it. as time goes by
we need to keep it up-to-date and there are two ways of doing that by fetching
and by pulling
git fetch origin will go out to the server and get any changes made since
you last cloned or fetched
fetching will pull the data into your local repository but will not merge it into
your work
you'll need to merge manually
using git pull origin will automatically fetch
and merge the changes from the remote branch into your current branch
when you're ready to submit your changes, commit your work
and then use get push origin master. we're telling git here to push ourchanges
to the remote repository known to us as origin
and commit them to the master branch at that point you'll be prompted for
credentials
and I'm gonna put in some fake credentials here so it's gonna fail
now at this point any changes that you've made will be committed to the remote
repository
to add addition remote repositories use
git remote add followed by the name you want to give the remote repo,
or the alias, and then the URL
and just like before, use the name
just like we did with origin from the cloned repo. there's quite a bit that I haven't
covered
but what we did cover is enough to get you up and running quickly
check out the git documentation and also have a look at pro
git which is now available as a free ebook and I'll put a link
down in the description. alright that's it for this episode
be sure to subscribe to our channel: and check out previous and future episodes
you have a request for an episode or you wanna be a guest on an episode
send me e-mail at c0deporn.show@gmail.com
c0deporn.show@gmail.com. thanks for watching!