Professional Documents
Culture Documents
1. Introduction
2. The Deck
3. Life in the Terminal
i. Why Terminal?
ii. Pimp your Terminal
iii. Meet Bash
iv. File Nav
v. Cheat sheet
vi. Open in VI
vii. In summary
4. Git workflow
i. Branching
ii. Branch Management
iii. Push
iv. Pull request
v. Merge the code
vi. Shortcuts using aliases
vii. Summary
5. The Git Demo
i. The folders
ii. The files
iii. The content
iv. Branching
v. The delta
vi. The merge
vii. Kill w/fire
6. Github
7. Fork a repo
8. Clone a repo
9. Auto complete
Presentation outline:
Life in the Terminal
What is branching?
Git workflow (branching and merging)
Demo outline:
Create local repo
Add content and commit code
Branch the code
Merge all the codes
Fork a repo
Workshop outline:
Getting Git Installed
Exercise Git workflow
Create a Github account and generate your SSH key
Fork a repo
Clone a repo
:wq
<file path>/**/*
esc
, ok?
Ok, we have all been there. This is weird. This is awkward. What did all of that mean?
Not to mention, your terminal window is probably all stupid looking, am I right? On a developers screen, it's all cool
looking. There is colored text that you can read and it's probably a little transparent. Yours, it's small, the type is hard to
read, and it's white and weird looking. No wonder you don't like going in there. It's freaking weird and scary looking, I get
that.
In this article, I aim to help change all of that and make your interaction with the Terminal a little bit easier.
Startup
Profiles
default
button at the bottom so that this becomes your default theme when opening a new
Terminal session
To the right of
Antialias text
ANSI Colors: For the inexperienced users I suggest leaving those alone.
Cursor: Select a style of cursor you like and if you want it to blink or not and you can change the cursor color.
Not sure what it is, but developers for some reason really like to tweak out their Terminal to look like old skool green
screen terminal computers. Myself, my first computer screen was amber, so I have a nostalgic connection to this and an
amber screen has been claimed to give improved ergonomics, specifically by reducing eye strain. There is no proof to
this, but who needs science?
a color and adjust the transparency. There is a feature to set a background image, but this tends to be really distracting.
Window size: This will set the default new open window size.
And that is it for here. At this point, you should have a Terminal window that is looking pretty cool and makes you feel a
little but more comfortable working with it.
Meet Bash
Ok, now that you have your Terminal window looking nice, the fun really starts as we get to know what is inside.
Meet Bash. Terminal is the app that runs Bash on your computer. What is Bash?
... an acronym for the Bourne-Again SHell, a pun on Stephen Bourne, the author of the direct ancestor of the
current Unix shell
That's not very useful, but it is interesting. What you really need to know is that when you are looking up more information
on how to do things in Terminal, you will more then likely find references to this thing called Bash. Don't get confused as
the answer you are looking for is most likely there.
Also, keep in mind that Bash is a fully featured environment that is able to run applications and completely interact with
it's host OS. This is extremely powerful and maybe you are seeing why developers prefer this.
But pay that no mind at this point. For our purposes, we are going to only go as far as the features that we need to
understand.
.bashrc, .bash_profile
Probably one of the more confusing things of working with Terminal and Bash is how they are configured. Bash uses two
(dot) files that are located in your computer's home directory. They are
.bashrc
and
.bash_profile
BTW, a (dot) file is any file in the computer's file system where the name's first character is a dot. As in
.bashrc
. The
service this provides is that the file is hidden from normal view.
OSX keeps you from being able to rename a folder or file in the standard GUI for this reason. But ... we can do this from
Bash.
.bash_profile : read and the commands in it executed by Bash every time you log in to the system
.bashrc : read and executed by Bash every time you start a subshell
When using these files, there are some actions best suited for the
.bashrc
.bash_profile
. Keeping this
.bash_profile
this to work, the two files need to be linked, we do this through what is called sourcing. By placing the following code in
your
.bash_profile
.bash_profile
.bashrc
file.
if [ -f ~/.bashrc ]; then
source ~/.bashrc
fi
Ok, at this time we will just let that sit there. At this point we haven't discussed how to find files in Terminal or how to open
and edit files either. Further down this tutorial I will illustrate how to edit the content of these files from within the Terminal.
File navigation
By now you should have a pretty cool looking Terminal window and have been introduced to some base concepts like
Bash and it's core config files. It's time now to learn how to navigate around in this new text based world.
When you first open Terminal you typically are placed in your home directory. So let's start looking and moving around.
This is simply to illustrate that you should enter this command into the Terminal window.
The first command we will learn is
learn is the
$ cd
$ cd
. This symbol is simply an alias to your home directory. So, in your Terminal, do the following:
$ cd ~
Doing this will put you in your home directory. To make sure, in the Terminal enter
$ pwd
Great. But at this point there is a good chance that your Terminal is not telling you very much information. You know
where you are, but what's in your current directory? To list out the contents of your directory, do the following:
$ ls
Great! Now you can see all the files and folders contained within your User's directory. This isn't very exciting, let's get into
some fun stuff. If you are like me, you have any number of files and folders on your Desktop. All the contents of your
Desktop are contained within your
Desktop
Desktop
by
$ cd Desktop/
$ ls
Remember those (dot) files? You may notice that when you do a
$ ls
you only see files and folders that you can see in
the standard OS GUI. Commands in Bash can have additional attributes passed into them called flags. To see the hidden
files on your desktop pass in the
-la
$ ls -la
Now, listed in the Terminal you should see hidden files and folders, also you can see permissions, file size, modified
dates as well as some other information. Here is an example from my Desktop directory.
Notice is that it may be difficult to distinguish between files and folders. How can we make this easer? Passing in the
flag with an
ls
-p
$ ls -p
Great! Now we can see the contents of your Desktop directory and easily tell the difference between a file and a folder.
Now we can easily see that my PeepCode content is in a directory.
$ cd
$ cd
into a folder on your desktop and get stuck? I told you how to go in, but not how to back out.
Changing directories backwards is just as easy, from within a directory, do the following:
$ cd ../
That command will back you out one level from where you are. If you wanted to back out two directories, simply add
another
../
like so:
$ cd ../../
By now I am betting that your Terminal window is looking a bit messy. By entering the clear command, this will clean up
your view and give you a nice clean Terminal window to work with:
$ clear
At this point, you are doing really awesome. You have mastered some of the core commands for using Bash in the
Terminal app.
touch
features, but the one that we care about is creating a new file when one does not exist.
To do this, simply use the
touch
command, add on the name of the file you want to create and the file extension. To
create a simple text file called "new-file" from within the Terminal, enter the following:
$ touch new-file.txt
Say you wanted to create a new "index.html" file? To do so, use the following:
$ touch index.html
$ touch style.css
I think you are starting to get the point here. Remember when we spoke of (dot) files and that you can't create them from
the default OSX GUI? This can easily be addressed in the Terminal by placing the (dot) in the name like so:
$ touch .config
Remember, you can't see this file in the normal OSX GUI, so from where you are, use the
ls -la
This brings us to the next part, how do you delete a file from the Terminal? To do this, we use the
which is short for remove. Using this command, we can remove that
.config
rm
UNIX command
following:
$ rm .config
Running this command will simply delete this file and only return feedback if there is an error, for example:
Let say for example that you are not really confident with this and want to make sure that you are deleting the correct file.
To do this, simply pass in the
-i
flag. This will instruct the command to prompt you for confirmation. Here is an example of
creating a file, using that prompt flag and addressing the prompt.
foo
mkdir
$ mkdir foo
ls -p
foo/
directory we created.
ProTip: You don't actually have to be in the directory you want to create a new directory in. Remember the
alias for
your Home directory? For example, imagine you are in your Dropbox folder and you want to create a new folder on your
Desktop. You could do the following:
The next real-world thing you will run into is how to make a directory structure that is x number of levels deep. Making a
directory, then changing into that directory just to make another directory is turtles all the way down.
There is a better way. When using the
mkdir
-p
leading up to the given directory that does not already exist. If it does exist, ignore the error. Let's have fun here, run the
following in your Terminal:
$ mkdir -p ~/Desktop/turtles/all/the/way/down
Now that we have mastered creating directories, what about deleting them? Remember how we used the
to delete a file? We need to use this, but you can't simply delete a directory, we need to add on the
-r
rm
command
to remove directories and removing the contents recursively beforehand. So to remove our turtles directory, we would run
the following:
$ rm -r turtles/
Let's imagine that there is a case where there would be non-existent files confirmation prompts that get in your way of
deleting these directories. What is common is to add on the
-f
$ rm -r -f turtles/
-rf
-f
flag is just common place and as a short hand, you can combine the
-r -f
flag to
$ rm -rf turtles/
-f
flag to force something and ignore any prompts, pay attention to what you are doing. This
tab
tab
key.
key twice and Terminal will list out all the possible
options.
Now that we have created all these files and directories using the Terminal, the next obstacle to over come is to move
and rename things.
Starting with the basics, renaming things in Bash uses the
mv
mv
command
takes two arguments, the first is the file you want to change and the second is the result you want.
$ mv <source> <target>
For example, using what we have learned so far and adding in the new
Desktop within a project directory and then rename it:
$
$
$
$
$
cd ~/Desktop
mkdir -p project/public/stylesheets
cd project/public/stylesheets
touch stylesheet.css
mv stylesheet.css app.css
mv
app.css
used for renaming is really to move things. Since we are still in that
the root of the
public
stylesheets
$ mv app.css ../../public/
In that example, we could also rename the file if needed, for example:
$ mv app.css ../../public/style.css
mv
command we
app.css
file up to
Moving directories is much like moving files. For example, let's say that we created a directory at the root of
javascripts
$ mv javascripts/ public/
public
mv
project
called
Renaming directories goes the same way. Say that we had a directory on the Desktop called
it to be
bar
foo
$ mv foo/ bar/
The last thing we will talk about here is the process of copying a file from one location to another. For this we need to use
the
cp
cp
is much like
mv , but instead
in the new location. For files, the process should be familiar by now:
$ cp <source> <target>
What you should also know is that in defining the target for the copied version of the file, you can also rename it. For
example, and what is very common is that in a project there will be an example configuration file. It is then left up to the
developer to copy that file, update the name and then edit the configurations:
$ cp .config.exmaple .config
Copying directories is much like copying files, except for the fact that they have directories within, so we need to pass in
the
-r
flag for recursive. It should also be noted that when you copy a directory, depending on how you refer to the
two.html
directory_1
and then
directory_2
. Inside
directory_1
is a file called
. In this first example, I will simply refer to the source and target:
one.html
. Inside
directory_2
is a
$ cp -r directory_1 directory_2
directory_1
directory_2
into the command on a directory, this will only copy the contents of the directory in to the new
location.
$ cp -r directory_1/ directory_2
This concludes the file navigation portion of this tutorial. If using Terminal is new to you and you made it this far without
throwing your computer out the window, I applaud you! This is a huge step forward and you are now moving onto bigger
and better things!
Description
Tab
Ctrl + A
Ctrl + E
Ctrl + U
Ctrl + K
Ctrl + W
Ctrl + T
Esc + T
Ctrl + R
Ctrl + L or Command + K
Ctrl + C
Ctrl + D
Core Commands
Prompt
Description
$ cd
Home directory
$ cd [folder]
Change directory
$ cd ~
$ cd /
Root of drive
$ ls
Short listing
$ ls -l
Long listing
$ ls -a
$ ls -lh
$ ls -R
$ sudo [command]
Run command with the security privileges of the superuser (Super User DO)
$ open [file]
Opens a file
$ open .
$ top
$ nano [file]
$ pico [file]
$q
Exit
$ clear
Clear screen
Command History
Prompt
Description
$ history n
Shows the stuff typed - add a number to limit the last n items
$ ctrl-r
$ ![value]
$ !!
File Management
Prompt
Description
$ touch [file]
$ pwd
$ ..
$ ls -l ..
$ cd ../../
Move 2 levels up
$.
Current folder
$ cat
Concatenate to screen
$ rm [file]
$ rm -i [file]
$ rm -r [dir]
$ rm -f [file]
$ rm -i [file]
$ cp [file] [newfile]
$ cp [file] [dir]
Directory Management
Prompt
Description
$ mkdir [dir]
$ mkdir -p [dir]/[dir]
$ rmdir [dir]
$ rm -R [dir]
Description
$ more
$ > [file]
$ >> [file]
$<
Help
Prompt
Description
$ [command] -h
Offers help
$ [command] --help
Offers help
$ [command] help
Offers help
$ reset
$ man [command]
$ whatis [command]
.bash_profile
. The trick here is that it's difficult to open hidden files using most
editors that rely on a typical finder. UNIX comes with a text editor called VI built in that you can access from the Terminal.
To get started, make sure that you are in your home directory:
$ cd ~
$ vi .bash_profile
In your Terminal, you will have open this file in VI mode, so things are a little different. In order to add content, you need to
hit the
-- INSERT --
export CLICOLOR=1
export LSCLOLOLORS=GxFxCxDxBxegedabagaced
esc
:wq
to VI.
Ok, for the fun part. If you do a
ls -p
.bash_profile
$ source ~/.bash_profile
Now, enter
ls -p
In conclusion
There is an amazing amount of material here to consume. If you are new to using the Terminal, you may have to run
through these a few times to really get them locked in. But trust me, once you start down this path, there is no turning
back. Running your computer from the Terminal is efficient, powerful and fast.
Basic branching
When working with a centralized workflow the concepts are simple,
master
deployable. With each now scope of work, aka feature, the developer is to create a new branch. For clarity, make sure to
use descriptive names like
transaction-fail-message
or
github-oauth
#Protip: Although you may have a feature like 'user login and registration`, this is not considered appropriate to create a
feature branch at this level, there is too much work to be done. It is better to break these large deliverables down to
smaller bits of work that can be continuously integrated into the project. Remember, commit early and often.
Before you create a branch, be sure you have all the upstream changes from the
origin/master
branch.
$ git branch
master
then switch
to master
The
git pull
git fetch
and
git merge
. When doing a
fetch
the resulting
commits are stored as remote branch allowing you to review the changes before merging. Merging on the other hand can
involve additional steps and flags in the command, but more on that later. For now, I'll stick with
git pull
Now that I am all up to date with the remote repo, I'll create a branch. For efficiency, I will use the following:
master
as well checkout out that new branch at the same time. Doing a
master
* my-new-feature-branch
git
master
github-oauth
and I needed to create a new branch and then checkout the new
at the end of that command, Git will create a new branch from master and then move me
Branch management
As I am working on my new feature branch, it is a good idea to commit often. This allows me to move forward without fear
that if something goes wrong, or you have to back out for some reason, I don't lose too much work. Think of committing
like that save button habit you have so well programed into you.
Each commit also tells a little bit about what I just worked on. That's important when other devs on the team are reviewing
my code. It's better to have more commits with messages that explain the step versus one large commit that glosses over
important details.
$ git status
This command will give you a list of all the updated, added and deleted files.
To add files, I can add them individually or I can add all at once. From the root of the project I can use:
$ git add .
In order to remove deleted files from the version control, I can again either remove individually or from the root address
them all like so:
$ git add -u
I'm lazy, I don't want to think, so the following command I make heavy use of to address all additions and deletions.
All the preceding commands will stage the updates for commitment. If I run a
presented differently, typically under the heading of
Changes to be committed:
git status
It is considered best to illustrate your comment in the tense that this will do something to the code. It didn't do something
in the past and it won't do something in the future. The commit is doing something now.
A bad example would be:
Comments are cheap. For more on how to write expressive commit messages, read 5 Useful Tips For A Better Commit
Message.
master
apply.
This will fetch and merge any changes on the remote repo into my local brach with the changes, thus now allowing you to
push.
.git/
directory will of course manage all my local branches, but my local repo is not always aware of any remote
branches. To see what knowledge my local branch has of the remote branch index, adding the
-r
flag to
git branch
will
return a list.
$ git branch -r
To keep my local repo 100% in sync with deleted remote branches, I make use of this command:
$ git fetch -p
The
-p
or
--prune
flag, after fetching, will remove any remote-tracking branches which no longer exist.
git pull
or
git fetch
will update my local repo's index of remote branches. As long as co-workers have pushed
their branch, my local repo will have knowledge of that feature branch. By doing a
branches. By doing a
git branch -r
git branch
I will see a list of remote branches. There is a good chance that the new feature branch
This command will pull it's knowledge of the remote branch and create a local instance for me to work on.
header.haml
header.haml
This experience also allows the peer reviewer to place a comment on any line within the update. This will be
communicated back to the editor of origin. This review experience really allows for everyone on the team to be actively
involved in each update.
Once the reviewer has approved the editors updates, there are two ways to merge in the code. One from the Github
interface and another from the command line.
Latest version
Make sure that I have the latest version of the feature branch from the remote repo
Branch is up to date
Make sure that the feature branch is up to date with
master
master
master
,I
Notice the
--no-ff
flag in the merge command. This flag keeps the repo branching history from flattening out. If I were to
look at the history of this branch, using GitX for example, when using the
--no-ff
illustrating the history of the feature branch. This is helpful information. If I didn't use this flag, then Git will move the
commit pointer forward.
I can either enter the
--no-ff
flag each time I merge or I can set this as my default. I prefer the default option. Running the
true
NOTE: there is a mild side-effect that will happen when you set this flag to
false
pull
forward your local repo and basically make this a new commit. That's ok, but you will see this in the commit logs
If you are ok with this, then keep the flag. If this annoys or bothers you, do not use the flag and set
--no-ff
manually with
each merge.
The
-d
flag for delete will typically delete any branch. Remember, you can't delete a branch you have checked out.
If you happen to see the following error when deleting a branch, then simply replace the
-d
with
-D
In Bash
Using Git and Bash is like using a zipper and pants. They just go together. Creating a Bash alias is extremely simple.
From your Terminal, enter
$ open ~/.bash_profile
This will open a hidden file in a default text editor. If you have a shortcut command for opening in an editor like Sublime
Text, use that to open the file. In the file add the following:
alias refresh="git checkout master && dskil && git pull && git fetch -p"
The alias
dskil
.DS_Store
.gitignore
version control, but I like to keep a clean house too. To make that work, add the following:
.bash_profile
refresh
In Powershell
If you are on Windows and using Powershell, you can use the same aliases, but the set up is different. The article
Windows PowerShell Aliases is a good tutorial of the process.
Summary
Following this simple workflow has helped keep my projects clean and
Git hell
But ... the story doesn't end here. Well, the post does, but the story does not. There are many more advanced features that
your team can use. I am sure some of you reading this will say "What about rebasing?" This is a perfectly practical
addition to this workflow and many teams use it. But out of all the teams I have ever worked for, only one has ever made
use of this feature. Just saying.
Outside of that, for more in-depth learning on Git, I invite you to read the Git book, it's free and contains awesome
learning.
Git Demo
The easiest way to understand what Git is doing is to 'see' what it is doing. For this demo, the exercise is simple, we will
use your desktop, a folder and some simple HTML files to illustrate what Git it really doing.
The folder
On your
/Desktop
gitDemo
. The following steps will make sure that you are on the Desktop
of your computer, make a new directory and change into that directory.
$ cd ~/Desktop
$ mkdir gitDemo
$ cd gitDemo/
Now that we have the folder we can make this into a Git repository. Any directory at any level can be made into a Git
repository (or repo for short). If at any point you are unaware of the status of the repo:
$ git status
Running the
status
gitDemo/
fatal: Not a git repository (or any of the parent directories): .git
This simply means that this dir is not a properly set up Git repo. To make this a repo, simply run the following command:
$ git init
Running this command you should see something similar to the following:
Running the
status
# On branch master
#
# Initial commit
#
nothing to commit (create/copy files and use "git add" to track)
That is a little bit of a mouthful, but nothing to be concerned with. Simply, what this means is, you are on the
branch and there is nothing yet to commit.
master
The files
Now that we have a dir that is a properly formatted Git repo, let's create a few new files for a demo web app that we can
being to add to version control.
First, let's add the
index.html
file:
$ touch index.html
Great. But we need some more stuff for our demo web app. We need our primary CSS and Js files too. To do this we
need to create the proper dir for each:
$ mkdir stylesheets
$ mkdir javascripts
Using the
cd
app.js
and a
app.css
file:
What's up with those commands? It's simple really, in Terminal you can string together commands using the
&&
operator.
stylesheets/
app.css
file
status
# On branch master
#
# Initial commit
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# index.html
# javascripts/
# stylesheets/
nothing added to commit but untracked files present (use "git add" to track)
master
javascripts/
and
stylesheets/
Untracked files
in the output.
dirs but they are not listed out? This is because when you
add a new dir and create new files, unless you tell Git not to, it will simply gobble up all the files in the dir, so there is no
need to list them individually.
Interesting experiment: Let's create a new dir and NOT put anything inside it and then run the
status
command again:
$ mkdir foo
$ git status
foo
is not in the output? That's weird? No, it's not really. Git tracks files, not directories. So, if you
create a directory and don't put in any files, even if they are empty files, Git will pass on the empty dir all together.
$ rm -rf foo
foo
dir:
The content
At this phase we have the dir, it's a repo and it has folders and files. Great. Now to add some content. Open each file and
add the following:
HTML
<h1>Hello World</h1>
CSS
h1 {
font-size: 8em;
}
JavaScript
status
single turned bit in these documents, it does not display this in the
It's time to get things tracking, so let's use the
add
status
output.
commit
$ git add .
#
#
#
#
#
#
#
#
#
#
#
status
On branch master
Initial commit
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: index.html
new file: javascripts/js.css
new file: stylesheets/app.css
What does
unstage
git add .
command, this updated the status of all the files in that directory to be
staged
means is that
the edits you have added are not yet committed to the repo.
If you were to try and push code or switch branches at this time, these changes would not do what you expect them to do.
In order to commit these changes to the branch, we need to run the
There are a few parts of this we should talk about. There is the
is the
-m
commit
commit
command.
flag that we need to pass in so that you can add a commit message. This is important as you need these
messages added to the log, or the individual commit messages are meaningless. We add the message at the end of the
command sequence using quotes
""
After running this command sequence, you should see the following in your Terminal:
# On branch master
nothing to commit, working directory clean
Great! All the code has been updated and committed to the
master
branch!
or
or
In both these cases, these messages when read by the other developers in the log send a confusing message. And the
last one ... well o_O
Think of things in this way, "This commit will ..."
Make sense?
Commit history
Ok now that we have committed some code, let's see the history of these events.
$ git log
commit 15d42d592fff5abe101e5985be0830d1bd03a1f1
Author: Dale Sande <dale.sande@gmail.com>
Date: Tue Jun 10 18:25:26 2014 -0700
update to function ...
Cool, now we know things about the code being committed to the repo. Want to know more?
Yes,
blame
index.html
is what we want to know about. This is a great way to see who did what on a
You can see the initial part of the hash, the time stamp and the code that was modified. NICE!
master
branch. The
master
for stating what is the core branch of code that everyone should be committing to. Some don't use
conventions like
master
and use
stable
So, how do we work with branches? Pretty simple really. The first thing we want to know what branches we have and
what branch we are on:
$ git branch
* master
master
should be highlighted. Great. This means that we have only one branch and that this is the one you
git checkout
new-branch
-b
is the name we passed in here. You can name a branch anything, but I suggest keeping
master
* new-branch
-b
The delta
These next steps will demonstrate how we can make some edits in this branch, commit them and then switch to see the
delta between the branches.
First, let's update some code in the
index.html
file. Open this up in your favorite text editor and add the following code:
<p>goodnight moon</p>
app.css
p{
font-size: 2em;
}
Cool, now we have a diff between what was originally in this branch and what we edited. Here there are a couple of
things we can do, bit for now let's get out status:
$ git status
# On branch new-branch
# 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: index.html
# modified: stylesheets/app.css
#
no changes added to commit (use "git add" and/or "git commit -a")
Ok, the next thing we want to do is commit these changes to THIS branch and switch back to the
master
branch:
$ git add .
$ git commit -m "update content and styles"
Doing a
git status
here we will see that there is nothing to commit and the working directory is clean. Cool! Now, let's
master
branch:
index.html
and
app.css
files. The code we just added and committed are GONE!!!! Ok, don't panic,
it's not really gone, it's just on the other branch. Let's switch back to make sure.
Blamo! All the code should be back. But, we need that code in
master
The merge
Getting your branched code merged into
know that we have a version of code on
code that we want merged into
master
master
new-branch
. It is the new
master`:
Ok, now we want to merge, but let's do a little check first. We can do a quick check to see what branches are merged and
not merged into
master
master
new-branch
in the list. Ok, let's merge these two. BUT, we need pass in the
--no-ff
this do?
The
--no-ff
flag prevents
git merge
from executing a "fast-forward" if it detects that your current HEAD is an ancestor of the
commit you're trying to merge. A fast-forward is when, instead of constructing a merge commit, git just moves your branch
pointer to point at the incoming commit.
Occasionally you want to prevent this behavior from happening, typically because you want to maintain a specific branch
topology (e.g. you're merging in a topic branch and you want to ensure it looks that way when reading history). In order to
do that, you can pass the
--no-ff
flag and
git merge
Ok, but this may have just got weird and will freak you out.
--no-ff
we didn't add a commit message. This is Git telling us that we didn't leave a commit message and it's asking us for one
now.
If we don't leave a message, then Git will insert one for us. So, do the following:
:wq
Weird, but trust me. Now you should see the following:
index.html
and
app.css
master
branch.
You may notice the out branch that we created when we created our feature branch and then it links back into the
branch. This is EXACTLY what we are looking for. This is the merge technique we want when using the
--no-ff
master
flag. If we
had not used that technique, we would see a single branch of code and that can be misleading when we are reviewing
our project history.
new-branch
BOOM! There is no coming back from that easily. But why would we want to keep that around? Once we merge the code,
the history and code are all now part of
master
and that's where we want it. Keeping that old branch around us useless to
us. When we want to add new code, we will create a new feature branch.
Github
Without a doubt, Git and Github are like peanut butter and jelly. Once you have registered yourself as a user on Github,
the next thing you need to do is establish a connection to Github using SSH.
$ cd ~/.ssh
$ ls -al
id_rsa.pub
or
id_dsa.pub
$ ssh-add ~/.ssh/id_rsa
~/.ssh/id_rsa.pub
file with a text editor. This is your SSH key. Select all and copy to your clipboard.
Now that you have the key copied, it's time to add it into GitHub:
1. In the user bar in the top-right corner of any page, click Account Settings
2. Click SSH Keys in the left sidebar.
3. Click Add SSH key.
4. In the Title field, add a descriptive label for the new key. For example, if you're using a personal Mac, you might call
this key "Personal MacBook Air".
5. Paste your key into the "Key" field.
6. Click Add key.
7. Confirm the action by entering your GitHub password.
$ ssh -T git@github.com
# Attempts to ssh to github
Don't worry! This is supposed to happen. Verify that the fingerprint in your terminal matches the one we've provided up
above, and then type "yes."
If that username is yours, you've successfully set up your SSH key! Don't worry about the "shell access" thing, you don't
want that anyway.
If you receive a message about "access denied," you can read these instructions for diagnosing the issue.
If you're switching from HTTPS to SSH, you'll now need to update your remote repository URLs. For more information, see
Changing a remote's URL.
master
, you can then create a pull request that the owner of the
project will be notified of. If the updates are accepted, the admin will merge your pull request and the codes will be
added to the project.
Clone a repo
$ git clone <repo url>
That's really it. There isn't much more to this. By running the command above, this will tell Git to go to the URL and pull all
the codes to your local computer.
To get the URL, go to the Github repo and in the lower right hand side there will be an aside with the title of HTTPS clone
URL
Simply copy the URL from the text field, an example from the Node project is:
https://github.com/joyent/node.git
And there you have it, you own all the codes!
.git-completion.bash
~/.bashrc
or
~/.bash_profile
after
PATH
__git_ps1
file ( git-prompt.sh ).
You can either source the
git-prompt.sh
that comes with your installed version of Git, if it has it, or you can download and
~/.bash_profile
source ~/.git-prompt.sh
Git status
This will display the branch name next to the folder name in the bash prompt.
Symbols after the branch name indicate additional information about the repo state:
*
<
>
: The branch is ahead of the remote branch (remote branch can be fast-forwarded)
<>
: The branch and remote branch have diverged (will need merge)