Upload
gabriele-baldassarre
View
610
Download
2
Embed Size (px)
Citation preview
Git for the absolute beginnerA walkthrough from the official manual
gabrielebaldassarre.com
Content
❏ Introduction to Version Control Systems
❏ How Git works
❏ Basic Commands
❏ Branching and Merging
❏ Some Useful Stuff
❏ Basic Configuration
Before starting: about Version Control
❏ Version Control is a system that records changes to a
file or a set of files over time so you can recall them
later.
❏ This allows you to revert files back to a certain state,
restore projects to a previous state, compare the
differences between file versions and so on.
❏ Changes are stored outside your working tree and in a
specific location you don’t actually have access: the
Repository.
Local Repositories
● In this configuration, files
versions are stored in a
specific location of your
local file system.
● This location is created
when you initialize a
project.
● You won’t access to this
location by hands, but
only using the client
commands. (ie. ‘git’)Every git project has a local repository!
It’s the hidden .git subdirectory of the working dir
Distributed Repositories● In this configuration, files
are tracked using a
versioning server available
to multiple locals.
● This server is used to sync
between local repositories
of various team members,
thus enabling
teamworking.
● It even boosts safety, as
each local is a full working
mirror of the remote
repository.
Git Philosophy
Git is version control system that acts like a miniature file system for storing
changes to files over time. It’s nothing more than a stream of snapshots.
If a file is not changed, only a link to the previous version is saved, not the file itself.
Working directory vs Repository
The idea behind git is to decouple
the working directory from the
Repository.
● The Repository, as said before,
is the place where all the
snapshots of your files are
stored. Definitive changes in
your files are saved there.● The working directory is a temporary mirror of
one specific snapshot (the latest, eventually)
to developers to code and test on. No deploy
is made from the working dir to the Repository
without user’s intervention.
Checkout
When you start coding, you first
make a checkout of the local
repository.
This simply copies the files from a
specific snapshot (typically the
most recent) from the local
repository to the working
directory. This operation let you to safely code on the
working directory without affecting the
Repository.
Stage
After you have made some
modifications you’re satisfied on,
you push the changes to the
Repository, creating a new
snapshot.
First of all, you stage modified
files you want to push into the
Repository to the staging area.
No changes are made to the
Repository yet!
Commit
Finally you’re ready to definitively
commit a file in the Repository.
This is the point when a new
snapshot is created.
Only staged files are committed.
If you make further changes on
the working directory without
stage them, they won’t be
committed.
Git Stages
At the end of the day, you just
need to remember that git allows
files to exist in one and only one
of those stages at a given time:
● Committed: the file has been safely
saved on the local repository;
● Modified: the file has been
modified, but not yet committed or
staged;
● Staged: the file has been marked to
be committed in the next commit
operation.
This is a typical (simplified) workflow.
1. You make a checkout of the local repository to have a fresh copy of the latest snapshot on the working directory;
2. You make some changes on a file on your working directory:
3. You stage the file, adding a snapshot of it to your staging area:
4. You definitively commit the staged file in your local repository.
File lifecycle: Tracked/Untracked
This diagram summarize the status a file must have when it is in the working
directory. The story begins with the tracking state.
● A file is said to be tracked if there’s evidence of it in the last snapshot in the local Repository;
● On other hands, it said to be untracked if no story of it is available (for example new files not yet
committed for the first time).
File lifecycle: Add a file
When you add an untracked file, it goes from the Untracked state directly to the
staging area.
● It will be added to the Repository during the next commit.
File lifecycle: Commit a file
When you make a commit, staging area will flush and the files in the working
dir goes to the Unmodified stage.
● This because files in the working dir are identically the same on corrispective in the Repository
● Only the file in the stage area, thus committed, goes to the Unmodified stage. Files not
committed will preserve their states.
File lifecycle: Modify a file
When you make a modification to a file in the working dir, it goes to the
Modified stage.
● This because the file in the working dir doesn’t match with the corrispective in the Repository
● A modified file won’t be automatically stage. You must manually stage it if you want so.
File lifecycle: Stage a file
All the files from the Modified stage can be staged as well.
● As said before, staged files will be pushed to the Repository during the next commit.
File lifecycle: Remove a file
On the other hand, from the Unmodified stage, a file can be removed. This
action forces the file on the Untracked stage.
● Removing a file from Git won’t automatically delete it from the working dir;
● It either doesn’t tell Git to ignore the file, but just to push to untracked stage (you can always
add it again, if you need so).
Git for the absolute beginnersBasic Commands
gabrielebaldassarre.com
The Git command line
● Git comes with a command line tool to access its virtual file system (the
local repository) and it’s available for almost any operating system.
● Several graphical tools exists, actually, but for the sake of knowledge, we’ll
focus on the native command line interface only, here.
● To invoke a git command, just call the git executable followed by one of the
supported virtual file system commands (ie git commit).
○ We’ll dig on the most important commands in details later on.
Getting a Git Repository
You can start working on a Git repository in two ways:
● Initializing a Repository into an existing directory.
○ This basically put that directory from when the command is triggered
and its subdirectories under version control.
○ The command to be triggered is git init
○ When you trig the command, a .git hidden subdirectory is created with
the local repository.
● Cloning an existing repository
○ This literally create a mirror of a distributed (remote) repository in a
new local repository.
○ The command to be triggered is git clone <Repository URL>
■ For example: git clone https://github.com/libgit2/libgit2 mylibgit
Getting the status of a local repository
One of the most important command in git is git status.
It is used to check the status of each files of the working directory against
their version in the latest snapshot of the local repository.
For example, let’s dig into a typical output:
$ git statusOn branch masterChanges to be committed: (use "git reset HEAD <file>..." to unstage)
new file: README
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: CONTRIBUTING.md
This suggests us that the working directory has two files to be checked: README, which is in the untracked state, and CONTRIBUTING.md, which is in the unstaged state.
Git add
● The same git command is used to track an untracked file and to stage a modified file: git add <filename>
● Following the previous example:
git add README to track the untracked file README
git add CONTRIBUTING.md to stage the working copy of CONTRIBUTING.md which underwent some
modifications from the latest checkout.
Getting the status after staging
If you trig a git status after one or more staging ops you’ll see something like:
$ git add README
$ git add CONTRIBUTING.ms
$ git statusOn branch masterChanges to be committed: (use "git reset HEAD <file>..." to unstage)
new file: README modified: CONTRIBUTING.md
As expected, git is suggesting that two files has been staged. They will pushed on the local repository during the next commit.
Any further changes made to these files after the git add command will not be committed. These changes would end up into a new, not yet staged, version of the file.
This would held into the apparently counter-intuitive behaviour of a file being marked as staged and unstaged at the time. The trick is that they are two different versions of the file.
Getting short status
While very comprehensive, git status is quite verbose. git status -s is often preferred
$ git status -s M READMEMM RakefileA lib/git.rbM lib/simplegit.rb?? LICENSE.txt
The left hand column indicates the file was staged. The right letter indicates the file was modified. Following the example:
README was modified, but not staged: it will not commit
lib/simplegit.rb was modified, then staged: it will commit
Rakefile was modified and staged (it will commit), then was modified again (these changes will not commit)
lib/git.rb was just added and staged: it will commit
LICENSE.txt was not added yet: it’s untracked and will not commit.
Viewing changes
git status only tells you if a file was modified or not, but it won’t show what
actually is changed.
If you need to know what has been changed, git diff is your friend
It show you the differences between the content of your working area and the
content of the staging area. In other words, it shows the changes you made
that you have not yet staged.
Similarly, the command git diff --staged option compares the content of your staging area with the last commit. In other words, it shows the changes in your staging area that you haven’t yet committed.
Very often, developers prefer to use an external graphical tool to dig into diffs.
Committing changes
To finally push the staged files into the local repository, use the git commit
command this way.
$ git commit -m “Very recommended commit description”
As you may read, a commit description is strongly recommended. Git will fill it with the output of git status command if you skip it.
If you know what are you doing, a very timesaving shortcut is the -a option, which stands for “add every modified file to the staging area and commit ‘em all”.
In other words, it’s an add and a commit baked altogether.
$ git commit -a -m “Very recommended commit description”
Removing files
To remove a file from the Repository and the working dir, you cannot simply
delete from the working dir, as it will still marked as a tracked (but unavailable)
file.
Using git rm <FILENAME> command will automatically i. mark the file as untracked and
ii. delete it from the disk.
If you want to keep the local copy of the file, use git rm --cached <FILENAME>.
This will put the file into untracked and ignored state, but will not delete it from
the disk.
You’ll need to trig a git add command to put it back into the local repository.
Moving (renaming) files
On a similar way, you cannot simply move (rename) a file into the working dir to
automatically reflect changes to the local repository.
Moving (renaming) a file in Git is nothing more than making a copy of a file to
the new location (with the new name) and delete the source.
git mv <FILENAME> <FILENAME_2> is the best shortcut to do so with just one command.
As for the rm operation, this applies to command line commands. GUIs would
probably have better automations for file system operations like the aboves.
Undoing things: discard a commit
If you realize that you have messed up a commit (ie. committed too early.
forgot a file, made a typo into the commit description) you can always try to
amend it.
When you amend a commit, you basically replace the latest commit with the
content of your staging area. The command to be triggered is git commit --amend
Remember that amending a commit is more like replacing a commit than
removing a commit.
As a consequence, if you amend a commit, but your staging is empty, the
amend will have no effect.
Undoing things: unstaging files
If you realize that you have staged the wrong file (ie you triggered a git add
command too early, or you triggered the fairy-killer git add * command) you can
try to unstage it.
The command to use is git reset HEAD <FILENAME>
This simply unstage a file: it won’t affect the content of the working directory.
But be very careful to not use the --hard option to unstage a file because it will
destroy your local file instead.
Undoing things: unmodifying files
If you realize that you won’t need to keep the changes you made to a file(s)
from the latest checkout and you want to redo from start from the latest
snapshot of the local repository, simply perform a checkout for that particular
file only.
$ git checkout -- <FILENAME>
Be careful that this will definitively overwrite the local version of the file.
Remember: anything that is committed is almost always recoverable if lost
(even if the commit was amended). But anything you lose that was never
committed is most probably lost forever.
Git for the absolute beginnersWorking with Remote Repositories
gabrielebaldassarre.com
Remote Repositories
Remote Repositories are versions of your Repository hosted on internet or a
network. Their centralized and accessible locations give you the possibility to
collaborate in a team.
You may have many of them, some of them with read-write access and others
with read-only access. Depending on your grants, you can pull data from the
repository or eventually push data on it when you need to share your work.
Popular platforms like GitHub and BitBucket are nothing more remote git
repositories on the internet.
Cloning a Remote Repository
When you start contributing to a project, or when you init a repository from
GitHub or similar, the first command you usually trig is clone.
As the name suggests, the command clones the remote repository in a new
local repository and automatically add the source as a remote for that brand-
new local repository.
$ git clone https://github.com/theclue/analytics-vagrant.git
Cloning into 'analytics-vagrant'...
remote: Counting objects: 1165, done.
remote: Total 1165 (delta 0), reused 0 (delta 0), pack-reused 1165
Receiving objects: 100% (1165/1165), 1.29 MiB | 320.00 KiB/s, done.
Resolving deltas: 100% (336/336), done.
Checking connectivity... done.
Checking out files: 100% (839/839), done.
Listing Remote Repositories
When you add a remote, you basically link a local repository to a remote one, in
order to be able to take them in sync.
You may have more than a remote connected to the same local repository:
● For example, you may have a production read-only remote repository to fetch data from
and a dev read-write repository to push your contributions to.
To list all the remotes you have for the local repository, use git remote
$ git remote -v
origin https://github.com/theclue/analytics-vagrant.git (fetch)
origin https://github.com/theclue/analytics-vagrant.git (push)
(Note: the -v option is to get the URL of a remote instead of the name only)
When you clone a remote repository, a remote called origin pointing to the
source of the clone is automatically added to the local repository.
Adding/Removing a Remote Repository
As said before, you may have multiple remotes for the same local repository.
Each of them is identified by a name and points to a specific url.
● Origin is just the default name for the remote automatically created when you clone a remote
repository. As fact, you may change or even delete it if you don’t need anymore.
To add a remote, use the git remote add command:
$ git remote add andy http://github.com/andy/andy-great.repo.git
Similarly, the git remote <remote.name> remove command is used to remove a remote,
while git remote rename <remote.name> <newname> is used to...guess what?
Interacting with Remotes: Fetch/Pull
Interacting with remotes means be able to get data from them and (if you have
the grants to do so) to push your contribs to it. To get data from a remote, you
basically have two commands: git fetch and git pull
● When you fetch data from a repository, you’re asking git to download data from the
remote to the local repository. Data is downloaded but is not merged to what you’re
working on until you merge it to the local branch. The command is: git fetch <remote>
<local branch) (ie git fetch origin master)
● If you want to fetch and merge data automatically , you’re basically making a pull.
The content of the working directory will be updated to the latest snapshot of the
remote repository. The format of the command is: : git pull <remote> <local branch) (ie git
pull origin master)
(More on branches and branching in the next section)
Interacting with Remotes: Push
On the other hand, to deploy data to a remote you have just one command: git push
● When you push data from a repository, local commits are uploaded to a specific
branch of the remote. The command is: git push <remote> <remote branch) (ie git push origin
master)
It’s important to note that the push will fail if someone else cloned and pushed to the
remote in the meantime. This happens because the remote repository is not consistent
with your due to her contribs made meanwhile.
● To complete your push, you first need to pull her contribs, check and (eventually) merge
them and finally push your commits again.
We’ve not talked about branches, yet. Just remember for now that a local branch named
master is automatically created when you clone a remote.
Git for the absolute beginnersBranching and Merging
gabrielebaldassarre.com
Anatomy of a Commit
Before introducing what branching is and how it’s so useful, we need to make a
step behind and talk about how a commit actually works.
As said before, a commit is a snapshot of content in the Repository.
But it’s very important here to note that each commit has a pointer to the
previous one. Altogether, they form a linked structure like a chain.
What is a Branch?
A branch is a simple, lightweight, movable, pointer between to one of the
commits of a Repository. When you perform a commit, the branch pointer move
forward automatically.
As said before, when you init (or clone) a Repository, a master branch is
automatically created for you.
Creating a Branch
When you create a new branch, you’re creating a new pointer to the same
commit you’re currently on. This is done with the git branch command.
Let’s say we want to start working on some experimental features of the code
we would like to test without the risk to break the master code currently in
production.
The best thing to do is to create an ad-hoc branch for that:
$ git branch testing
The HEAD pointer
The special pointer HEAD is used by git to know on which branch currently it is.
As you may see in the picture, creating a new branch doesn’t automatically
switch to it: we’re still on the master branch.
The git log --decorate command could be really useful identify where
all the branches are actually pointing to (ie commit f30ab):
$ git log --oneline --decoratef30ab (HEAD, master, testing) add feature #32 - ability to add new34ac2 fixed bug #1328 - stack overflow under certain conditions98ca9 initial commit of my project
Switching between Branches
To switch between different branches of the local repository, use the git checkout
command.
git checkout testing
Can you see where the HEAD pointer is after been switched?
Committing to a Branch
If we made some modification to the local repository while on the testing branch
and commit them, we’re going to end up with a situation like the one depicted
below.
The testing branch has moved forward as expected, but the master
branch is still pointing to the commit it was when we triggered
the git checkout testing command.
c2b9e
Diverging Branches
Let’ say that, while working on the experimental features on the testing branch,
a critical issue of the code currently in production is discovered and must be
fixed with the highest priority.
We obviously need to switch back to the
master branch to start working on the fix.$ git checkout master
The HEAD pointer is rewinded to an older state and we can start
working on the master branch as we left our before.
c2b9e
Diverging Branches/2
Finally, let’s say we produced a fix for the critical issue and we committed it on the master branch. The history of commits will look like the picture below.
The point here is that using branches, we were able to preserve
multiple statuses of the code, as each branch is completely
insulated from the others.
Since switching back and forth between branches is as easy as
launch a command, this is an extremely powerful feature to use!
One important note about branching
There’s a very important fact to never forget while working with multiple branches:
Switching between branches will actually modify the content of the working directory.
Thus, when you make a git checkout, the content on the working directory is replaced with the snapshot of the repository the branch you are switching to.
This means that if you have some uncommitted changes into the branch you’re leaving they will be lost forever!
● As a matter of facts, git won’t actually allow you to switch branches at all if you have some uncommitted changes.
● We’ll look later a very useful command to allow you to save (but not commit) the changes you made in a branch before switching to a new one.
Introduction to Merging
Last section we ended up with two branches (master and testing) in different states.
Now, let’s say that we had the possibility to work again on our experimental features - the testing branch - until we feel confident to release it in production - the master branch.
Preserve different branches of your code is nothing if you don’t have the possibility to merge it to the main/master branch sooner or later, thus releasing it into the wild.
In the following slides we’re going to present a new scenario when this is proven useful.
Merging/1
Similar of what we have done in the previous section, let’s say that, while working on the code, we are going to handle the minor issue number 53.
As said before, the best way to handle it is to create a new branch and leave the master branch untouched:
$ git checkout -b issue53
<doing some changes…>
(Note: checkout -b command is a shortcut to create
and immediately switch to a new branch)
Said that, we produce a fix for the issue that ends up with the
commit C3. Please note that the master branch is still unchanged.
Merging/2
Now, let’s say that, while working on iss53 branch, we get a call to immediately code up an hotfix for a critical bug on the master branch. We then switch back to master, then create a new branch hotfix for the task.
$ git checkout master
$ git checkout -b hotfix
<doing some changes…>
Then, we start working on the hotfix and commit our changes
in what ends up in the commit C4. Note that the master branch
is still unchanged!
We make some tests and decide that the hotfix is ok...and now?
It’s time to merge it into the master branch!
Fast-forward Merge
Perform a merge is just easy as triggering the git merge command from the branch you want to merge into and specifying the branch to merge from. In other words:
$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874cFast-forward index.html | 2 ++ 1 file changed, 2 insertions(+)
This is the easiest thing you can do: the fast-forward merge.
During this kind of merge, the pointer to the destination branch
(master) is simply moved fast-forward to the merging branch (iss53).
Deleting a Branch
After the merge between master and hotfix, most probably we won’t need the latter anymore. We can safely delete it:
$ git branch -d hotfix
This ends up with the tree commit depicted below:
Now, let’s say that we can safely switch back working on the
code for the issue 53 to push the HEAD to iss53:
$ git checkout iss53
Merging from diverging branches
After some more work, we produce the code for fixing the issue 53 and we commit it in C5.
The point here is that the code from commit C4
(the one which include the hotfix) is not included
on the iss53 branch.
You can still perform the merge, but git has to do some homework to allow you to do so.
Merging from diverging branches/2
To perform a merge from diverging branch, the command is the same, but the output is kind different:
$ git checkout master
$ git merge iss53
Merge made by the 'recursive' strategy.index.html | 1 +1 file changed, 1 insertion(+)
Instead of directly merging, Git identifies the
elements of a three-way merge between the
merging-from snapshot, the merging-to
snapshot and the common ancestor of both.
Merging from diverging branches/3
Then, Git automatically creates a new commit from the three snapshots and push forward the merging-from branch (the master branch, in this case) to this new location.
If you don’t need the iss53 branch
anymore, since it merged already,
the remove command is the same: git branch -d iss53
The -d option is valid to remove only merged branches.
If you want to delete an unmerged branch, then the option to use is -D
Watch out using it, as no undo is possible when you delete an unmerged branch!
Conflicts during Merge
Sometimes the merge operation doesn’t go smoothly. This often happens when you modify the same part of a file in two different branches (ie the hotfix and the iss53 branches)
When it happens, Git will suspend the merging operation with a message similar to:
$ git merge iss53Auto-merging index.htmlCONFLICT (content): Merge conflict in index.htmlAutomatic merge failed; fix conflicts and then commit the result.
In these situation, the git status command will give you which files are currently locking the merge:
$ git statusOn branch masterYou have unmerged paths. (fix conflicts and run "git commit")
Unmerged paths: (use "git add <file>..." to mark resolution)
both modified: index.html
no changes added to commit (use "git add" and/or "git commit -a")
Conflicts during Merge/2
If you open the offending files, you may notice some dividing lines like ====== or <===== splitting the code.
Git is basically merged the two different versions of the files (from hotfix and iss53, here), asking you to clean-up choosing which content to keep and which one to trash.
After you have resolved all the conflicts (trig a git status command to be sure you did), you just need to finalize the merge with a manual git commit operation.
Please note that you can launch the git commit command without any options.
In facts, the commit message will be filled with the description of the merge (but you may still override it with the -m option, if you need so).
Listing Branches
A common way to list all the branches in your local repository is to use the git branch command without any options.
$ git branch iss53* master testing
(Note: the * mark identifies the branch you’re currently on)
Very handful commands are then:
● git branch -v to show the last commit near the branch names;● git branch --merged to list only merged branches. As said before, it’s almost
always fine to remove already merged branches with the git branch -d command;
● git branch --no-merged to list only unmerged branches.
Working with Remote Branches
Remote-tracking branches are references to the state of branches on a Remote Repository.
They take the form of <remote.name>/<remote.branch> (ie origin/master)
When you clone a remote repository, these branches are automatically created:
● A remote-tracking origin/master
● A local master branch tracking origin/master
Working with Remote Branches/2
If you do some work on the local master branch, while someone else do some on the remote master branch, then their histories will start to move forward differently.
Look how the origin/master remote reference on your computer is still pointing to the same snapshot of the remote repository!
Working with Remote Branches/3
If you want to fetch the remote data you actually haven’t yet on your local repository, just launch a git fetch <remote.name> command to push origin/master (in this example) fast-forward.
Please note that origin/master and (local) master are still unmerged!
You need to merge them, or use the pull command that is nothing more than a fetch+merge shortcut.
Working with Remote Branches/4
You’re not limited on using only one remote. Of course, it could be quite confusing to remember ‘em all. Here is an example where two different remotes have been pulled on a local repository.
It’s here where git status, git branch and git remote will be your best friends!
Pushing
When you want to share a branch with the world, you need to push it up to a remote where you have write access to.
Your local branches aren’t automatically synchronized to the remotes you write to – you have to explicitly push the branches you want to share. That way, you can use private branches for work you don’t want to share, and push up only the topic branches you want to collaborate on.
The command here is git push <remote.name> <local branch to push to remote>
$ git push origin hotfixCounting objects: 24, done.Delta compression using up to 8 threads.Compressing objects: 100% (15/15), done.Writing objects: 100% (24/24), 1.91 KiB | 0 bytes/s, done.Total 24 (delta 2), reused 0 (delta 0)To https://github.com/schacon/simplegit * [new branch] hotfix -> hotfix
This basically creates a branch on the remote with the same name of the local branch and push the content into it.
Tracking Branches
It’s important to know that if someone else from your team fetches the origin/hotfix from the remote, she won’t get a local hotfix branch. For that, she still need to merge it with a local branch.
So, to make things clever, it’s better to setup a local branch to track a remote branch. Tracking branches are local branches that have a direct relationship to a remote branch. The command is git checkout -b <branch> <remotename>/<branch>
$ git checkout -b hotfix origin/hotfixBranch hotfix set up to track remote branch hotfix from origin.Switched to a new branch 'hotfix'
● If you’re on a tracking branch and launch a command, Git automatically knows which server to and branch to touch.
● And yes, the local master branch created during a remote repository clone is obviously a tracking branch of origin/master!
Pulling
Remote trackings and git fetch <remote> command won’t change the content of the working directory at all. Not until you merge it, of course.
To make things faster, Git gives you the possibility to pull data from a remote branch to a local tracking branch.
The command is: git pull <branch>
It’s nothing more than a fetch command immediately followed by a merge command performed on a tracking branch.
As it’s on a tracking branch, you don’t need to specify nothing more on the command line for the magic to happen.
Useful commands for remote branches
We’re going to close the section enlisting some other very useful commands while dealing with remote branches:
● git branch -vv is the option to use when you want to see all your tracking branches of the remote repository;
● git fetch --all is the command to use to fetch from all your remote branches at once;
● git push origin --delete <remote.branch> is the command to use to delete a remote branch.
● If you want to create a tracking branch with the same name of the remote is tracking on, you can use the shortcut git checkout --track <remote>/<branch>
Inspecting Remote Branches
Working with branches and remotes together could be confusing. For example:
● To which remote branch the local branch will be pushed?
● Where is the remote HEAD?
The git remote show <remote.name> command is a life-safer in those situations:
$ git remote show origin
* remote origin
Fetch URL: https://github.com/theclue/analytics-vagrant.git
Push URL: https://github.com/theclue/analytics-vagrant.git
HEAD branch: master
Remote branch:
master tracked
Local branch configured for 'git pull':
master merges with remote master
Local ref configured for 'git push':
master pushes to master (up to date)
This helps you to identify what will actually happen in case of push and pull on
various branches.
Rebasing
Finally, we’re going to just introduce the other kind of merge available in Git:
the rebase.
Let’s start from the typical divergent situation we all know.
The command is very similar to merge, but it’s backward: you launch it from the
branch you want to rebase from specifying the branch you want to rebase to.
For example:
$ git checkout experiment$ git rebase masterFirst, rewinding head to replay your work on top of it...Applying: added staged command
Rebasing/2
When we launch the rebase command, Git basically perform a linearization of
commits to get something like:
As you may see, it just shifts up the experiment
branch, without merging it with master. In facts, we need to merge in the usual
way:
$ git checkout master$ git merge experiment
Although the output is the same, rebasing can be useful if you want a linear commit
history or if you haven’t the grants to push local branches (like ‘experiment’) to a remote.
Git for the absolute beginnersReally Useful Stuff
gabrielebaldassarre.com
Tagging
A tag is a unmovable reference to a snapshot you decide to annotate and label.
It can be really useful when you’re going to identify a release, a capstone or a
milestone in your code.
The most common kind of tag one is the annotation:
$ git tag -a v1.0 -m “first release in prod - version 1.0”
By default, tags are not pushed to a remote unless you manually do that:
$ git push origin v1.0
Some other useful commands about tags:
● git tag -a -m “v0.9” a4cf34 to later tag a commit behind the HEAD, specifying its hashkey;● git tag to show all the tags;● git checkout -b version2 v2.0.0 to creating a new branch from the snapshot the tag is
referring to.
Stashing
The stash gives you the possibility to leave a branch without committing
changes. It basically saves the content on the working dir in a temporary buffer
of unfinished changes.
This is proven to be a life-saver when you must leave a branch in a messy state
due to other duties and you don’t want to commit the changes yet until you’ve
the possibility to work again on them. The command is easy to remind:
$ git stashSaved working directory and index state \ "WIP on master: 049d078 added the index file"HEAD is now at 049d078 added the index file(To restore them type "git stash apply")
Since you’re not limited to one stash, you have a command to list ‘em all:
$ git stash liststash@{0}: WIP on master: 049d078 added the index filestash@{1}: WIP on master: c264051 Revert "added file_size"stash@{2}: WIP on master: 21d80a5 added number to log
Stashing/2
To apply a previous staged stash, use the git stash apply command:
$ git stash apply On branch master Changed but not updated: (use "git add <file>..." to update what will be committed)
modified: index.html modified: lib/simplegit.rb
As you may notice, this restores the stash and modifies the working dir, but it
does not stage the restored files, nor commit them. You must do it in the usual
ways with git add and git commit.
If you don’t specify which stash to restore, Git will assume you want the most
recent one. If it’s not the case, you must specify the name in the apply
command:
$ git stash apply stash@{2}
Stashing/3
As usual, some useful additional commands about stashing:
● git stash apply --index is a very useful option when you already have some staged files
when you restore a stash, as git will try to stage the files again after the restore. You may
end with some file conflicts very similar to those you would experience during a merge (and
you have to fix them in the same way).
● git stash --keep-index to stash only unstaged files. Useful when you want to commit only
part of the changes and stash the rest.
● git stash --include-untracked to track both tracked and untracked files. This because by
default, stash won’t save untracked files.
● git stash branch testchanges to create a new branch from the content of the stash.
Finally, a very special mention goes to the git clean command, which allow you to
get rid of all the uncommitted changes of the working directory, but without
stashing them.
Basic Configuration
The Git client is configured using the git config command.
These directives applies to the current local repository only by default, but you
can force them to apply to all your Repositories with the --global option.
There are tons of useful configurations available and there is no room here for
sum them up. But two of them among others are absolutely mandatory: they
allow you to set your name and your email for pushing and committing.
$ git config --global user.name "John Doe"$ git config --global user.email [email protected]
For other useful configuration options, you should really check the official
manual. They could be real time-savers.
Getting Help
❏ Official Git Manual: this is absolutely the place for
getting help. All the diagrams of this course have been
borrowed from there, actually.
❏ http://git-scm.com/doc
❏ Stack Overflow
❏ http://stackoverflow.com/questions/tagged/git
❏ Books
❏ “Pro Git” by Scott Chacon (aPress)
❏ “Version Control with Git” by John Loeliger (O’Reilly)
Contacts
❏ Tutorials on open analytics development
❏ Data mining with R
❏ Ready-made data jobs
❏ Visual Analytics Use Cases
https://gabrielebaldassarre.com
Need help? Questions? Consulting needs?
https://gabrielebaldassarre.com/contacts/
@cerealping