- Used SVN, TFS and git
- Fell in love with git - because it changed (for better) my way of working
- Am by no means a git expert
- Respect and understand people who use other VCSs
- What's a VCS and why do I need one?
- Configuration
- Using git
- Branching & Merging
- Branching Model
- Tools?
--->
--->
--->
- Traveling back in time
- Revert files back to a previous state
- Revert the entire project back to a previous state
- Compare changes over time
- Who introduced an issue and when
- Sharing
- Collaborating
- Paralelizing your work
- Solving multiple issues separately
- Make a quick fix in the midst of developing a feature
--->
--->
-
The caveman solution
-
Muggles still use this everyday
- Designers
- Managers
- Lawyers
- Doctors
-
Good
- Pretty straightforward
-
Bad
- ???
--->
--->
- Good
- ???
- Bad
- Hard to manage over time
- Hard to collaborate
- Single point of failure
--->
-
CVS, Subversion, etc.
-
Standard solution for many years and still used by many
-
Good
- Easier to collaborate
- Not too hard to understand
- Easier to administer (if you're a devop)
-
Bad
- Single point of failure
- Hard to work without access to the server
--->
- git, Mercurial, etc.
- Clients fully mirror the repository
- No single point of failure
- Best for collaboration - multiple remotes
--->
--->
- Speed - simple design
- Non-linear development (thousands os parallel branches)
- Fully distributed
- Scale - able to handle large projects like the Linux kernel efficiently
--->
- While other VCSs represent commits as file based changes, git takes snapshots of the files
- git stores data as snapshots of the project over time
- Nearly every operation is local
- Local history
- Database is replicated when cloning
- You can commit without network connection
- Integrity is built-in
--->
- Linux
- Rails
- Microsoft
- ...
- elgin?
--->
--->
- System setting :
/etc/gitconfig
- Global user settings :
~/.gitconfig
- Repository settings :
.git/config
- Windows:
C:\Documents and Settings\$USER\.gitconfig
--->
git config --global user.name "John Doe"
git config --global user.email johndoe@example.com
git config --global core.editor vim
gif config --global merge.tool vimdiff
git config --list # show all config values, last ones have priority
git config user.name # show config value
--->
git help <verb>
git <verb> --help
man git-<verb>
Example:
git help config
- IRC - irc.freenode.net
- #git
- #github
- Free book! - ProGit
- Ask me!
--->
git init
### Cloning an existing repository git clone
--->
- Untracked - changes are not recorded by git
- Tracked
- unmodified - no changes since last snapshot
- modified - modified since last snapshot
- staged - a modified snapshot which is ready for commit
--->
--->
$ git status
# On branch master
nothing to commit (working directory clean)
## After creating a new file $ touch README $ git status # On branch master # Untracked files: # (use "git add ..." to include in what will be committed) # # README # nothing added to commit but untracked files present (use "git add" to # track)
--->
$ git add README
## Now let's check the status again $ git status # On branch master # Changes to be committed: # (use "git reset HEAD ..." to unstage) # # new file: README #
--->
$ vim index.html (& make some changes)
## What's the status now? $ git status # On branch master # Changes to be committed: # (use "git reset HEAD ..." to unstage) # # new file: README # # Changes not staged for commit: # (use "git add ..." to update what will be committed) # # modified: index.html #
--->
$ git add index.html
## And the status? $ git status # On branch master # Changes to be committed: # (use "git reset HEAD ..." to unstage) # # new file: README # modified: index.html #
--->
- git add to track new files
- git add to stage files
- git add to mark conflicts as resolved
--->
$ git diff // changes still unstaged
$ git diff --cached // changes staged to commit
--->
$ git commit -m "Learning git is fun!"
### This will commit everything which is staged
--->
--->
$ git commit -a -m "fix stuff"
### This will stage and commit the files in a single operation
--->
- Are in the present tense
- Start with a capitalized letter
- Have a subject that does not exceed 50 chars
- Have a thourough message body that explains in detail what was changed and why. This message is linewrapped at 72 chars.
--->
$ git commit --ammend
--->
$ git rm file.txt // removes from repo & working directory
$ git rm --cached file.txt // removes from repo
--->
$ git mv file_from file_to
## Is just a short hand for $ mv README.txt README $ git rm README.txt $ git add README
--->
$ EDITOR .gitignore
IDE files, local settings, etc...
--->
$ git log
--->
$ git reset <filename>
--->
$ git checkout <filename>
--->
$ git remote -v
$ git remote add <name> <url>
--->
$ git fetch <remote>
## Fetch + Merge with branch $ git pull
## Pushing $ git push
--->
--->
--->
--->
## Snapshots FTW!--->
--->
## HEAD--->
## HEAD--->
A commit consists of
- Message
- Author
- Commiter
- Date
- Pointer to tree (snapshot)
- Pointer to previous commits
--->
- A branch in Git is simply a lightweight movable pointer to one of these commits.
- When you commit, the branch moves forward, pointing to the new commit.
- A branch in git is actuality a simple file that contains the 40 character SHA–1 checksum of the commit it points to
--->
- Creating a new branch is just creating another pointer!
- Creating a new branch is as quick and simple as writing 41 bytes to a file (40 characters and a newline).
- Branching is a LOCAL operation, no server communication is needed
- Switching branches changes the files in the working directory
- A special pointer called HEAD always points to the current branch
--->
--->
$ git branch <branch_name>
$ git branch -d <branch_name>
$ git checkout <branch_name>
$ git checkout -b <branch_name>
$ git branch
--->
--->
You should branch everytime you do something new.
Branch for:
- Fixes
- Features
- Experiments
--->
### If you do not care about versions + Keep master stable!
### If you want to release specific versions + Develop on master + Branch to stable release versions + Fix bugs on release versions branches and merge onto master + Never merge master onto release version branches
--->
--->
- Do work on a web site
- Create a branch for a new story you’re working on
- Do some work in that branch
- Revert back to your production branch
- Create a branch to add the hotfix
- After it’s tested, merge the hotfix branch, and push to production
- Switch back to your original story and continue working
--->
--->
$ git checkout -b iss53
Switched to a new branch "iss53"
--->
$ vim index.html
$ git commit -a -m 'added a new footer [issue 53]'
--->
$ git checkout master
Switched to branch "master"
--->
$ git checkout -b hotfix
Switched to a new branch "hotfix"
$ vim index.html
$ git commit -a -m 'fixed the broken email address'
[hotfix]: created 3a0874c: "fixed the broken email address"
1 files changed, 0 insertions(+), 1 deletions(-)
--->
$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast forward
index.html | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
--->
$ git checkout iss53
Switched to branch "iss53"
$ vim index.html
$ git commit -a -m 'finished the new footer [issue 53]'
[iss53]: created ad82d7a: "finished the new footer [issue 53]"
1 files changed, 1 insertions(+), 0 deletions(-)
--->
$ git checkout master
$ git merge iss53
Merge made by recursive.
index.html | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
--->
--->
--->
$ git merge iss53
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
$ git status
index.html: needs merge
# On branch master
# 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)
#
# unmerged: index.html
#
--->
<<<<<<< HEAD:index.html
<div id="container">Awesome!</div>
=======
<div id="container">
Wunderbar!
</div>
>>>>>>> my-other-branch:index.html
Remember: HEAD
is was what you had checked out when you ran your merge command
--->
$ git add <filename>
## Graphical tool to solve the issues $ git mergetool
## Continue merge after solving conflicts $ git commit
--->
Reapplying a diverging branch onto another
git checkout <diverging_branch>
git rebase master
After rebasing, a merge of master with diverging_branch will fast-forward master
--->
- Finds the common ancestor of the two branches (base)
- Gets the diff of each commit of the branch you’re on, from the base
- Saves those diffs to temporary files
- Resets the current branch to the same commit as the branch you are rebasing onto
- Applies each change (diff) in turn
--->
--->
--->
$ git checkout experiment
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: added staged command
--->
$ git checkout master
$ git merge experiment
--->
--->
--->
Rebasing replays changes from one line of work onto another in the order they were introduced, whereas merging takes the endpoints and merges them together.
The only difference between merging and rebasing is the resulting history
--->
--->
- Don't be afraid to branch and merge frequently
- At the begining, ad if you're working on the same branch: ignore rebase
$ git commit -m "Fancy message" // Many of these
$ git pull origin develop // This merges. Simpler
$ git push origin develop // Push commits
--->
- Release your code more frequently
- Keep a production ready state of your product
- Don't wait for nobody to push that hotfix
- Better collaborate on features
--->
- Stashing
- Cherry-pick
- Interactive staging
- Interactive rebasing
--->
- It's different
- It will take some time to get the handle
- You wont spend 2 hours doing merges anymore :-)
--->
- You shouldn't use git (or other VCS) to just 'save your work' at the end of the day
- Craft your commits - it will help you
- Treating commits as snapshots brings advantages
- Branch and Merge are friends - don't be afraid of them!
--->