On Github zfjagann / git-slides
How to use git to improve your day-to-day development tasks
Commits can be created with the commit command and viewed with the log command.
Commits also have a SHA-1 name, which are 40 characters long, but can be abbreviated to anything longer than 4 characters.A pointer to a commit
Branches can be managed with the branch command and changed with the checkout command.
The location of another git repository
Remotes can be managed with the remote command and synchronized with the commands fetch, pull, and push.
A pointer to the current branch
The HEAD behaves like a branch, and is moved by the checkout command.
A cache between the working directory and the repository
The index can be modified with the commands add and reset.
The local repository lives in the .git directory.
Initializes a new git repository in the current directory.
$ git init Initialized empty Git repository in /Users/zeal/git/.git/
Copies the contents of a repository
$ git clone git@github.com:zfjagann/Demo.git Cloning into 'Demo'... remote: Counting objects: 53, done. remote: Compressing objects: 100% (32/32), done. remote: Total 53 (delta 9), reused 49 (delta 5) Receiving objects: 100% (53/53), 4.68 KiB, done. Resolving deltas: 100% (9/9), done.
Adds changes to the index
$ git add updated-file
Lists information about the workspace, index, and repository
$ git status # On branch new # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # new file: updated-file #
Creates a commit with the contents of the index
$ git commit -m 'Added updated-file' [master 1797f98] Added updated-file 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 updated-file
Lists a history of commits in the repository.
$ git log commit fb61a552913bf97de6055c823bafb463375f3492 Author: zeal <zeal@skybox.com> Date: Wed Jun 12 18:26:59 2013 -0700 Added readme.Can do some amazing stuff with log and fancy formatting.
Use branch to create a new branch.
$ git branch feature-branch
* fb61a55 - Added readme. (HEAD, feature-branch, master)
Use checkout to change branches.
checkout -b is an alias that will create and switch to a new branch
$ git checkout feature-branch Switched to branch 'feature-branch'
When changes are committed, the are committed to HEAD.
$ git commit -m 'Added a new feature.' [my-branch c4dcc14] Added a new feature. 0 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 feature.rb
* c4dcc14 - Added a new feature. (HEAD, feature-branch) * fb61a55 - Added readme. (master)
When changes are committed into two branches independently, the branches diverge.
$ git checkout master $ git add quick-fix.rb $ git commit -m 'Added a quick fix.' [master 127d4e1] Added a quick fix. 0 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 quick-fix.rb
* 127d4e1 - Added a quick fix. (HEAD, master) | * c4dcc14 - Added a new feature. (feature-branch) |/ * fb61a55 - Added readme.
There are two ways to join branches:
A merge joins the two diverged tree segments with a new commit combining their changes.
Before
* 127d4e1 - Added a quick fix. (HEAD, master) | * c4dcc14 - Added a new feature. (feature-branch) |/ * fb61a55 - Added readme.
$ git checkout master $ git merge feature-branch Merge made by the 'recursive' strategy. 0 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 feature.rb
After
* aaac857 - Merge branch 'feature-branch' (HEAD, master) |\ | * c4dcc14 - Added a new feature. (feature-branch) * | 127d4e1 - Added a quick fix. |/ * fb61a55 - Added readme.Merge commits muddle history, and are difficult to read.
If one of the tree segments doesn't contain changes the merge is called a fast-forward.
$ git checkout feature-branch $ git merge master Updating c4dcc14..aaac857 Fast-forward 0 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 quick-fix.rb
* aaac857 - Merge branch 'feature-branch' (HEAD, feature-branch, master) |\ | * c4dcc14 - Added a new feature. * | 127d4e1 - Added a quick fix. |/ * fb61a55 - Added readme.This occurs when the common ancestor of two commits is one of the two commits. A fast-forward is the ideal type of merge, where one side can simply be moved forward in the history.
A rebase will replay history from one branch on top of another.
Before
* 127d4e1 - Added a quick fix. (master) | * c4dcc14 - Added a new feature. (HEAD, feature-branch) |/ * fb61a55 - Added readme.
$ git checkout feature-branch $ git rebase master First, rewinding head to replay your work on top of it... Applying: Added a new feature.
After
* d44f56b - Added a new feature. (HEAD, feature-branch) * 127d4e1 - Added a quick fix. (master) * fb61a55 - Added readme. (origin/master)
Rebase destructively changes your commit history, so can be dangerous to use.
Do not rebase commits that have been pushed to a remote.
The rebase command has an interactive mode that allows for manipulating commits in various ways:
Remotes are how git keeps track of linked repositories.
The remote command can be used to list servers or modify them.
$ git remote origin $ git remote -v origin git@github.com:zfjagann/Demo.git (fetch) origin git@github.com:zfjagann/Demo.git (push) $ git remote add other git@github.com:rpk/Demo.git $ git remote -v origin git@github.com:zfjagann/Demo.git (fetch) origin git@github.com:zfjagann/Demo.git (push) other git@github.com:rpk/Demo.git (fetch) other git@github.com:rpk/Demo.git (push) $ git rm other $ git remote origin
Branches on remotes are represented locally as:(remote)/(branch)
For example:origin/master
Local branches can be setup to track remote branches.
$ git checkout --track origin/new-branch Branch new-branch set up to track remote branch new-branch from origin. Switched to a new branch 'new-branch'Tracking is git's way of making sure that the branches are synchronized.
The push command will transfer local commits to a remote repository.
$ git push origin master Counting objects: 4, done. Delta compression using up to 8 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 269 bytes, done. Total 3 (delta 0), reused 0 (delta 0) To git@github.com:zfjagann/Demo.git fb61a55..25c1f9f master -> masterTracking is git's way of making sure that the branches are synchronized.
The fetch command will fetch all commits at each repository to their local remote branches.
$ git fetch remote: Counting objects: 34, done. remote: Compressing objects: 100% (12/12), done. remote: Total 23 (delta 19), reused 15 (delta 11) Unpacking objects: 100% (23/23), done. From github.com:zfjagann/Demo.git a198ec0..00e78cd master -> origin/master
The pull command will internally do a fetch immediately followed by a merge.
$ git pull origin master From ../Demo2 * branch master -> FETCH_HEAD Updating fb61a55..25c1f9f Fast-forward 0 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 file
The pull command can be told to do a rebase instead by passing the --rebase argument.
$ git pull --rebase origin master remote: Counting objects: 3, done. remote: Compressing objects: 100% (1/1), done. remote: Total 2 (delta 0), reused 1 (delta 0) Unpacking objects: 100% (2/2), done. From ../Demo2 * branch master -> FETCH_HEAD First, rewinding head to replay your work on top of it... Applying: Added second file.
The pull command allows for ease of use. The fetch command allows for inspection and manual merging of remote changes.
A workflow is a procedure for collaborating on a project with git.
Atlassian has descriptions for four common workflows on their workflows page.
A submodule is a repoisitory nested within another repository.
Submodules can be created with the submodule command.
$ git submodule add git@github.com:zfjagann/Demo.git Cloning into 'Demo'... remote: Counting objects: 3, done. remote: Total 3 (delta 0), reused 3 (delta 0) Receiving objects: 100% (3/3), done. $ git status # On branch master # # Initial commit # # Changes to be committed: # (use "git rm --cached <file>..." to unstage) # # new file: .gitmodules # new file: Demo
Using the foreach command, you can run a given command in each submodule of the current repository.
$ git submodule foreach git rev-list -n 2 HEAD Entering 'Demo' d44f56b7831ec44dd087ea499e5896c5d85475df 127d4e1e43ba59ba10190b1716dfa6975086952eThis is extremely useful and can be used to branch all projects in a group. Also, the --recursive flag allows for nested submodules.
Using the foreach command, you can run a given command in each submodule of the current repository.
$ git submodule foreach git rev-list -n 2 HEAD Entering 'Demo' d44f56b7831ec44dd087ea499e5896c5d85475df 127d4e1e43ba59ba10190b1716dfa6975086952eThis is extremely useful and can be used to branch all projects in a group. Also, the --recursive flag allows for nested submodules.
Aliases can be used to shorted long commands.
Similar to bash aliases.Bisect is a tool to binary-search through bash history to find the cause of a bug.
Suppose you know a feature is broken, and you know it worked 6 months ago. Bisect will allow you to binary-search through the history to find the commit that caused the bug.The log command can be used to print pretty branch graphs.
$ git log --graph --oneline * e58a2a2 Merge branch 'master' of git@github.sky:DataSystems/JanusCommon.git |\ | * 17348c7 fixing broken migration | * 1e23c55 [Janus-683] flattened camera into collection | * 031b1c1 [JANUS-115] Added resource for reserving SAWs. * | 051ded6 Merge branch 'master' of git@github.sky:DataSystems/JanusCommon.git |\ \ | |/ | * f4f6ced [JANUS-686] Updated window generator to generate SkyNode windows. | * 71ae40f Updated pkg file to include populateGroundStations | * ae31ec8 Correct customer Ids | * 4a54f3b Merge branch 'saw_windows' | |\ | | * 23f7001 Renamed populate script. * | | 8292b66 [NEXUS-6] WIP |/ / * | 709e857 [NEXUS-6] WIP on sending SkyNode Blackouts Event JSON from Janus to Nexus * | 3609edd [NEXUS-6] configuring TELNotifier to pass SkyNode Blackout Window info to Nexus * | 42fc224 Merge branch 'master' of git@github.sky:DataSystems/JanusCommon.git